I currently have a running service that receives messages from sockets every time another user sends someone a message. Now in the activity I can easily call a dialog to display a notice that a message has been received, however I want to do that from the running service. How can I get about with this?
Here is my running service.
public class MyService extends Service implements ChatCallbackAdapter {
public StartSocket connect;
public static Context mContent;
private ConnectSocket connectsocket;
final Context context = this;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onStart(Intent intent, int startId) {
System.out.println("Service is running");
connectsocket= new ConnectSocket(this);
connectsocket.start();
connect=new StartSocket();
}
public void startNotification(){
Intent intent = new Intent(this, ReceiveNotification.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
// Build notification
// Actions are just fake
Notification noti = new Notification.Builder(this)
.setContentTitle("Received a message")
.setContentText("Subject").setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.addAction(R.drawable.ic_launcher, "Rply", pIntent)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Hide the notification after its selected
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);
}
#Override
public void callback(JSONArray data) throws JSONException {
// TODO Auto-generated method stub
}
#Override
public void on(String event, JSONObject data) {
// TODO Auto-generated method stub
}
#Override
public void onMessage(String message) {
// TODO Auto-generated method stub
}
#Override
public void onMessage(JSONObject json) {
// TODO Auto-generated method stub
}
#Override
public void onConnect() {
// TODO Auto-generated method stub
}
#Override
public void onDisconnect() {
// TODO Auto-generated method stub
}
#Override
public void onConnectFailure() {
// TODO Auto-generated method stub
}
#Override
public void onMessageReceived(Message m) {
// TODO Auto-generated method stub
System.out.println("Received a message in service");
if(m.status.equals("ready")){
connectsocket.login(SaveSharedPreference.getUserName(getApplicationContext()), SaveSharedPreference.getUserId(getApplicationContext()));
connectsocket.subscribe();
}
if(m.status.equals("message")){
//getMsg(m.msg, m.name);
startNotification();
System.out.println("Received a message "+m.msg+" and a name "+m.name);
final String name=m.name;
final String pid=m.pid;
final String msg=m.msg;
//Intent intenter=new Intent(TabExercise.this, CreateNotification.class);
//startActivity(intenter);
//runOnUiThread(new Runnable(){
//public void run(){
//Handler handler = new Handler(Looper.getMainLooper());
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
context);
alertDialogBuilder.setTitle(name+" just sent you a message");
alertDialogBuilder.setMessage("Click yes to go to the message");
alertDialogBuilder
.setCancelable(false)
.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
Intent inte=new Intent(MyService.this, Chat.class);
Bundle extras=new Bundle();
extras.putString("name", name);
extras.putString("pid", pid);
extras.putString("msg", msg);
inte.putExtras(extras);
startActivity(inte);
dialog.cancel();
}
})
.setNegativeButton("No",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
//}
//});
}
}
}
You have 2 options:
Use Messenger Pattern as explained in documentation here.
Use LocalBroadcastManager to send out a broadcast from service, and make the target activity implement BroadcastReceiver to listen to that broadcast.
An advantage the Messenger have is that service can select to notify one particular messenger of all its clients.
Related
I have a Service with a Notification with a Progress Bar inside. This Service is started when i open the Main Activity and works fine. But, when i close Main Activity (onDestroy() is called) the Notification is like refreshed. This is the code of my Service.
#Override
public void onCreate() {
super.onCreate();
Mypreferences prefs = new Mypreferences(this);
String minutes = prefs.getStringValueOf("Minutes");
final NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
d = Integer.valueOf(minutes)*60;
builder.setSmallIcon(R.drawable.ic_action_about);
builder.setContentTitle(getString(R.string.app_name));
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<d;i++) {
builder.setProgress(d, d-i, false);
builder.setContentInfo(d-i+"/"+d);
notificationManager.notify(0, builder.build());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
Integer d it's 60 and countdown works fine but when i close MainActivity if for example ProgressBar is at 40, return to 60. Why? How can i solve?
Service code
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
pref = new SharedPref(this);
map = pref.getAllPrefs();
boolean delay = pref.loadBooleanPref("delay");
String delayTime = pref.loadStringValue("DelayTime");
if(delay && delayTime != null) {
new CountDownTimer(TimeUnit.MINUTES.toMillis(Long.valueOf(delayTime)), 1000) {
#Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
getInfo();
}
}.start();
} else {
getInfo();
}
}
i am doing an application that will notify the user after 2 weeks. but i set the timer in 2 mins so i could test if my application will notify the user. my problem is when i turn on the notification and close my app. i will get an error in 2 minutes no notification but when my app is running the notification is working fine. In the logcat my error is in Bundle showData = i.getExtras(); i think the problem is when i closed my app, the Bundle passData is getting null?
PhoneInformation.java
case R.id.bTurnOn:
Bundle passData = new Bundle();
Intent intent = new Intent(PhoneInformation.this,NotificationService.class);
passData.putInt("keyid", rowId);
intent.putExtras(passData);
startService(intent);
break;
NotificationService.java
public class NotificationService extends Service{
int rowId;
private Timer timer = new Timer();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Toast.makeText(this, "OnCreate()", Toast.LENGTH_SHORT).show();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "OnDestroy()", Toast.LENGTH_SHORT).show();
}
#Override
#Deprecated
public void onStart(final Intent i, int startId) {
// TODO Auto-generated method stub
super.onStart(i, startId);
final Handler handler = new Handler();
Timer timer;
TimerTask timertask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#SuppressWarnings("deprecation")
public void run() {
Bundle showData = i.getExtras();
rowId = showData.getInt("keyid");
Bundle passData = new Bundle();
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(NotificationService.this,SMSPhoneMessage.class);
passData.putInt("keyid", rowId);
notificationIntent.putExtras(passData);
PendingIntent pendingIntent = PendingIntent.getActivity(NotificationService.this, 0, notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
Notification notification = new Notification(R.drawable.ic_launcher, "New Message", System.currentTimeMillis());
notification.setLatestEventInfo(NotificationService.this, "New Message", "Please come to me immediately", pendingIntent);
nm.notify(123, notification);
}
});
}
};
timer = new Timer();
timer.schedule(timertask, 10000);
}
}
I am new to android. I am trying using AIDL.
What I am tryng is take initial value i.e 0 from the Textview and tryng to increment its value by calling a method defined in aidl file(using service.)
But the TextView is not updating on button click.
Kindly Help.
Here is my code.
CounterService.aidl
package com.example.counter;
interface CounterService {
int updateCounter(in int var);
}
CounterServ.java (Exposing service)
package com.example.counter;
public class CounterServ extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new CounterService.Stub() {
#Override
public int updateCounter(int var) throws RemoteException {
// TODO Auto-generated method stub
return var + 1;
}
};
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
User Activity using service.
public class MainActivity extends Activity {
CounterService myservice;
AdditionServiceConnection connection;
class AdditionServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder Service) {
myservice = CounterService.Stub.asInterface(Service);
Toast.makeText(MainActivity.this, "Service connected", Toast.LENGTH_LONG)
.show();
}
public void onServiceDisconnected(ComponentName name) {
myservice = null;
Toast.makeText(MainActivity.this, "Service connected", Toast.LENGTH_LONG)
.show();
}
}
private void initService() {
connection = new AdditionServiceConnection();
Intent i = new Intent();
i.setClassName("com.example",com.example.counter.MainActivity.class.getName());
boolean ret = bindService(i, connection, Context.BIND_AUTO_CREATE);
}
private void releaseService() {
unbindService(connection);
connection = null;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initService();
Button update = (Button)findViewById(R.id.button1);
update.setOnClickListener(new View.OnClickListener() {
TextView value=(TextView)findViewById(R.id.textView1);
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int val,res=-1;
val=Integer.parseInt(value.getText().toString());
try{
res=myservice.updateCounter(val);
}
catch(Exception e)
{e.printStackTrace();}
value.setText(res);
}
});
}
protected void onDestroy() {
releaseService();
}
}
Convert res into text format by applying following code and try
String str = String.valueOf(res);
value.setText(str);
I got where I was lacking. I didnt register this service in the menifest file and therefore was not able to use it.
I am creating application which contains service that suppose to listen to calls,
and pop up an alert dialog after call has ended, the issue is, that as long as the activity running or in the background, the service works and the dialog pop up, but when I close the activity, the dialog wont pop up, as like the listener will not listen anymore to calls.
need help please!
this is how I call the service from my activity:
public void onClick(View v) {
switch (v.getId()) {
case R.id.start:
startService(new Intent(getBaseContext(), PhoneService.class));
break;
case R.id.stop:
stopService(new Intent(getBaseContext(), PhoneService.class));
break;
}
}
the service class:
public class PhoneService extends Service {
private static String TAG = "SERVICE";
int currentState;
Context context;
String incomingNumber;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
// starts the service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "FirstService started");
context = this;
TelephonyManager telephony = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
// object
CallListener listener = new CallListener();
telephony.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
// keeps the service going until explicitly stops
return START_STICKY;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i(TAG, "FirstService destroyed");
}
the listener class:
public class CallListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (TelephonyManager.CALL_STATE_RINGING == state) {
// Incoming call handling
Log.i(TAG, " ring ring ring" + incomingNumber);
currentState = state;
}
if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
// Outgoing call handling and answer
Log.i(TAG, " ofhook" + incomingNumber);
currentState = state;
}
if (TelephonyManager.CALL_STATE_IDLE == state) {
// Device back to normal state (not in a call)
Log.i(TAG, " idle" + incomingNumber);
if (currentState == TelephonyManager.CALL_STATE_OFFHOOK) {
Toast.makeText(context,"phone number dialed is "+ PhoneService.this.incomingNumber,Toast.LENGTH_SHORT).show();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Who is this person?").setCancelable(false).setPositiveButton("1",new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog, int id) {
}
})
.setNegativeButton("0",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.getWindow().setType(
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alert.show();
}
currentState = state;
}
}
}
Change your service to derive from IntentService and remove the overrides for onBind and onStartCommand (let the system handle those).
Put your code in the onHandleIntent override.
The different service types are handled differently - a bound service only operates while the activity is running, but an intent service can be started at any time. You can read more about service types here.
On my MapActivity, when you tap on an ItemizedOverlay, it displays the
Title
Snippet / Messsage in a TextView and changes each time another ItemizedOverlay is clicked or tapped
I have created an ImageButton with a phone image on it and i am trying to call an Array Intent to it
So basically, when Users Tap on Overlay1, and then decide to tap on the Phone Image Button the number stored in the intent, changes to Overlay1's number and so they can call Overlay 1
and if they tap on Overlay 2, then the number would change accordingly etc
my Code is as follows:
List<Overlay> mapOverlays;
List<Intent> mapIntents;
NewItemizedOverlay itemizedOverlay;
Intent intentCall;
GeoPoint point = new GeoPoint((int)(51.555890943494276*1E6), (int)(-0.39989858865737915*1E6));
OverlayItem overlayitem = new OverlayItem(point, "Greenwood Veterinary" , "57 Station Approach, South Ruislip, Ruislip, Middlesex, HA4 6SL, 020 8845 8144");
itemizedOverlay.addOverlay(overlayitem);
Intent vet1 = new Intent(android.content.Intent.ACTION_DIAL,Uri.parse("tel:020 8845 8144")); // i created this in a similar fashion to the itemizedOverlay
intentCall.?(vet1); // i wanted to try and do the same thing with the addOverlay but i cant seem to find the correct method of doing this
GeoPoint point2 = new GeoPoint((int)(51.598707*1E6), (int)(-0.393416*1E6));
OverlayItem overlayitem2 = new OverlayItem(point2, "MediVet Pinner" , "2A Pinner Green, Pinner, Middlesex, HA5 2AA, 020 8866 0727");
itemizedOverlay.addOverlay(overlayitem2);
Intent vet2 = new Intent(android.content.Intent.ACTION_DIAL,Uri.parse("tel:020 8866 0727"));
ItemizedOverlay:
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private ArrayList<Intent> cIntents = new ArrayList<Intent>();
Context mContext;
public NewItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
public NewItemizedOverlay(Drawable defaultMarker, Context context)
{
super(boundCenterBottom(defaultMarker));
mContext = context;
}
public void addOverlay(OverlayItem overlay)
{
mOverlays.add(overlay);
populate();
}
public void addOverlay(OverlayItem overlay, Intent intent)
{
mOverlays.add(overlay);
cIntents.add(intent);
populate();
}
#Override
protected OverlayItem createItem(int i) {
// TODO Auto-generated method stub
return mOverlays.get(i);
}
protected Intent createCall(int c)
{
return cIntents.get(c);
}
#Override
public int size() {
// TODO Auto-generated method stub
return mOverlays.size();
}
public int callsize()
{
return cIntents.size();
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
Intent callItem = cIntents.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setIcon(android.R.drawable.ic_dialog_info);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
dialog.setNeutralButton("Call", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
VetNumber. //Not sure how to exactly call the Intent
}
});
dialog.show();
return true;
}
}
If anyone could help, i would be very grateful
Thank You
Maybe it's too late for you, but you can start a new intent if you know the context where you are. If you're working with MapActivity and ItemizedOverlay you can get the context in LocalizacionItemizedOverlay.
Context mContext;
public LocalizacionItemizedOverlay(Drawable defaultMarker, Context context) {
super(boundCenterBottom(defaultMarker));
mContext=context;
}
Then in the onTap function you can write some similar to:
dialog.setPositiveButton("Ver", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent nextScreen = new Intent(mContext, YourActivity.class); //define the intent
nextScreen.putExtra("definicionURL",definicion.url); //pass variables
mContext.startActivity(nextScreen); //launch the intent
}
});
This has been my first post in stackoverflow.com and I want to say something to all people posting solutions here: thank you very much.