In my project I am using binder mechanism to communicate to remote service. The remote service class will call JNI function and updates to UI for every 10 seconds. The JNI function has below code
static int n = 100;
return ++n;
This JNI function calling in Service class and updating to UI like below
public class MyService extends Service{
private static final String TAG = "MyService";
private final Handler serviceHandler = new Handler();
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
System.out.println("inside service onCreate");
Log.d(TAG, "entered onStart");
serviceHandler.removeCallbacks(sendUpdatesToUI);
serviceHandler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
1. private IMyService.Stub bioStub = new IMyService.Stub() {
2.
3. #Override
4. public int intFromJNI() throws RemoteException {
5. // TODO Auto-generated method stub
6. int libData = Abcd.intFromJNI();
7. System.out.println("inside ****** stub"+libData);
8. return libData;
}
};
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
System.out.println("inside binder ");
return bioStub;
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
Log.d(TAG, "entered Runnable");
try {
bioStub.intFromJNI();
serviceHandler.postDelayed(this, 10000);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
This service class is calling in Activty
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Intent serviceIntent=new Intent();
serviceIntent.setClass(context, MyService.class);
boolean ok=bindService(serviceIntent, mServiceConnection , Context.BIND_AUTO_CREATE);
Log.v("ok", String.valueOf(ok));
}
private ServiceConnection mServiceConnection=new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName arg0, IBinder service) {
// TODO Auto-generated method stub
System.out.println("inside ServiceConnection");
myService = IMyService.Stub.asInterface(service);
try {
Log.d("Client", "entered mServiceConnection");
8. int jniValue = myService.intFromJNI();
9. System.out.println("value if JNI==>"+jniValue);
10.
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
}
};
Here my problem is, The service class is not updating UI for every 10 seconds and the value is not incremeting in UI but the value is incrementing for every 10 seconds in service class i.e the print statement below is updating for every 10 seconds which is in line Number 7 in above code(Service).
System.out.println("inside ****** stub"+libData);
But I want to it update in UI also. i.e the statement line num 10.
System.out.println("value if JNI==>"+jniValue);
I`t is not happening in my code . How to solve this one .`
You are missing any way for the Service to tell the Activity about new events. The call from the Activity to the Service, intFromJNI, is a one-off function call which happens just once - it has no ongoing responsibility for telling the UI about changes in future.
You should add some listener class. For example, add IMyServiceListener.aidl with something like this:
package com.something;
interface IMyServiceListener {
void valueUpdated(int newValue);
}
And then in IMyService.aidl add this:
import com.something.IMyServiceListener;
void addListener(in IMyServiceListener newListener);
Then, within your IMyService.Stub class you will need to implement addListener - you should add the resulting object to some array of listeners, and call valueUpdated on each listener, each time the value changes.
Within the activity, you should call myService.addListener and pass in some object which receives notification of the changes. You can then display that on the UI within the activity.
Related
I am trying to re-initiate the entire function of download and uppdate service when an AsyncTask in my activity is being called but I am not sure if I am doing something wrong. Currently, I have a refresh button that initiates the AsyncTask:
Refresh function that initiates AsyncTask:
final ImageView refreshBtn= (ImageView) findViewById(R.id.spin_refresh);
Log.i("RootActivity:setupHeader","******ImageView refreshBtn******");
//Listening to Button Click by User
refreshBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("RootActivity:setupHeader","******OnClick,Call RefreshTask******");
//CALL ON THE CLASS OF REFRESHTASK ASYNCTASK
RefreshTask refreshtask = new RefreshTask();
refreshtask.execute();
}
});
Once my refresh function is called, it will call onto the refreshtask within my activity:
public class RefreshTask extends AsyncTask <Void,Integer,Long> implements Observer{
// SET THE PARAMETERS FOR REFRESHTASK IN ASYNCTASK: PRE-EXECUTION, PROGRESS UPDATES & POST-EXECUTION
private Context context=null;
private DownloadService callback =null;
protected boolean exitAsync = false;
public static Hashtable<String, Download> downloadList;
final public static String PATH = "/sdcard/DCIM/100MEDIA/";
private static final Long START_STICKY = null;
Intent intent;
ListView lv;
RelativeLayout rl;
protected String dSResponse = null;
public void UIThreadProgress(Context context, DownloadService callback) {
this.context = context;
this.DownloadService = DownloadService;
}
//PROCESS IN CALLING THE DOWNLIST WHILE IN BACKGROUND
protected Long doInBackground(Void...params){
// TODO Auto-generated method stub
Log.i("----------RefreshAsyncTask----------", "doInBackground");
try {
// ====================DownloadService
Thread.sleep(10000);
while (this.callback.condition())
Intent i= new Intent(context.this, UpdateService.class);
Intent I= new Intent(context.this,DownloadService.class);
// potentially add data to the intent
context.this.startService(i);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}while (!exitAsync);
return START_STICKY;
}
#Override
public void update(Observable observable, Object data) {
// TODO Auto-generated method stub
//UpdateServiceStatus
}
//HANDLES EVENTS ON THE UI-POST-EXECUTE
#Override
protected void onPostExecute(Long result){
super.onPostExecute(result);
lv.findViewById(R.id.spin_refresh).setVisibility(View.VISIBLE);
Log.i("----------RefreshAsyncTask----------", "onPostExecute");
//GIVE FEEDBACK ON THE USER INTERFACE
Toast.makeText(context, "Your document has been refreshed and contains the updated documents!", Toast.LENGTH_LONG).show();
// After the process in doInBackground has been completed
}
}
Please help, I am trying to re-instantiate the download and update service when AsyncTask is being called.
I can't understand why you start a service inside a thread. You should start a thread in a service instead. Check Local Service sample in this link:
http://developer.android.com/reference/android/app/Service.html
In your onClickListener just unbind service and bind it again. It will refresh your service. In onCreate method of your service start your download or update in a thread.
Note: It is better to use another thread mechanism for network service. AsyncTask is good for short-lived operations.
#Override
protected void onPostExecute(Long result){
super.onPostExecute(result);
lv.findViewById(R.id.spin_refresh).setVisibility(View.VISIBLE);
Log.i("----------RefreshAsyncTask----------", "onPostExecute");
//GIVE FEEDBACK ON THE USER INTERFACE
Toast.makeText(context, "Your document has been refreshed and contains the updated documents!", Toast.LENGTH_LONG).show();
RefreshTask refreshtask = new RefreshTask();
refreshtask.execute();
// After the process in doInBackground has been completed
}
I have a sound file running in a loop on a service.
The activity that starts the service also has a button. When I press the button I want the sound file in the service to stop playing, i.e kill the service. Have been unsuccessful so far as when I call stopService() the service continues to run.
Any Ideas? Thanks.
Activity
public class AlarmPage extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_page);
TextView timeview = (TextView)findViewById(R.id.timefiled);
final Button dismissButton =(Button)findViewById(R.id.dismissButton);
Bundle b = getIntent().getExtras();
String hrval = b.getString("HR");
String minval = b.getString("MN");
timeview.setText(hrval + ":" + minval);
final Intent alarmring = new Intent(this, alarmringService.class);
startService(alarmring);
dismissButton.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent alarmmenu = new Intent(getApplicationContext(),SetAlarmsActivity.class);
startActivity(alarmmenu);
System.out.println("Button:" + dismissButton.isPressed());
stopService(alarmring);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.alarm_page, menu);
return true;
}
}
Service
public class alarmringService extends IntentService{
public alarmringService(){
super("alarmringService");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.drawable.startrekcommsound);
mp.setLooping(true);
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.start();
}
}
I can't see why it doesn't work since I'm not an expert, but to fix your problem you could use intents. By the way, IntentService stops itself when it has no more work!
Try this: Send to the IntentService an Intent with a command saying to stop itself.
Then in onHandleIntent() check if this was the request and call stopSelf() from inside the Service.
Moreover, I don't know how MediaPlayer works, but maybe it has his own thread and you should stop this thread too!
I want to send data from one application A to other application B using AIDL file. My appl A is like below,
public class LibValue {
public static native int intFromJNI(int n);
static {
System.loadLibrary("hello");
System.out.println("LibValue : Loading library");
}
I am getting value from JNI file to above class. The data from above class to send another app B using AIDL service is like below.
IEventService.aidl
interface IEventService {
int intFromJNI(in int n);
}
for this I written IEventImpl.java class
public class IEventImpl extends IEventService.Stub{
int result;
#Override
public int intFromJNI(int n) throws RemoteException {
// TODO Auto-generated method stub
System.out.println("IEventImpl"+LibValue.intFromJNI(n));
return LibValue.intFromJNI(n);
}
}
To access above class I writtn service class like below
public class EventService extends Service {
public IEventImpl iservice;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Log.i("EventService", "indside onBind");
return this.iservice;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
this.iservice = new IEventImpl();
Log.i("EventService", "indside OncREATE");
}
#Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
return super.onUnbind(intent);
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
this.iservice = null;
super.onDestroy();
}
All above classes are server side. The below class is Client(app) class to access data.
public class EventClient extends Activity implements OnClickListener, ServiceConnection{
public IEventService myService;
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_client);
button = (Button)findViewById(R.id.button1);
this.button.setOnClickListener(this);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (!super.bindService(new Intent(IEventService.class.getName()),
this, BIND_AUTO_CREATE)) {
Log.w("EventClient", "Failed to bind to service");
System.out.println("inside on resume");
}
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
super.unbindService(this);
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
this.myService = IEventService.Stub.asInterface(service);
Log.i("EventClient", "ServiceConnected");
}
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.d("EventClient", "onServiceDisconnected()'ed to " + name);
// our IFibonacciService service is no longer connected
this.myService = null;
}
I am trying to access data from service class but not able to find out the way. can anybody tell how to access data from service to client application ?
Thanks
I want to make Programm where a countdown is included. I want the countdown to keep on running even if the app is closed. I know i should use getter and setter.
Edit: Every time I press the button, I get an error. Does any one know how i can fix this?
starting the Service:
public void onClick(View arg0) { //countdown starts by preesing a button
// TODO Auto-generated method stub
ssf = Integer.parseInt(essf.getText().toString());
Intent openCountDownService = new Intent("julian.mangelberger.ultravioletobservation.COUNTDOWNSERVICE");
startService(openCountDownService);
}
Service:
import julian.mangelberger.ultravioletobservation.TabMainActivity;
import android.app.IntentService;
import android.content.Intent;
public class CountDownService extends IntentService {
public CountDownService(String name) {
super(name);
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
while (TabMainActivity.progressBarStatus <= 100) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
TabMainActivity.progressBarStatus++;
TabMainActivity.progressbar1.setProgress(TabMainActivity.progressBarStatus);
}
}
}
I am building a native android app, where I want the user to be automatically logged out (kind of session timeout) after a period of inactivity say 5 mins.
It is a standalone app and there are multiple screens in the App. I am not maintaining any user session with a server.
P.S: I found a possible solution in writing a time out event for android. But that is suitable only for a single Activity application. Can anyone suggest a similar solution for a multi-activity app ?
Ok so in response to the link you posted, why not follow that approach but create some sort of abstract base activity, that all of your other activities extend. So essentially you are adding a timeout to each activity, but your base activity will handle this, your child activities will not need to know what is going on.
public class LogoutService extends Service {
public static CountDownTimer timer;
#Override
public void onCreate(){
// TODO Auto-generated method stub
super.onCreate();
timer = new CountDownTimer(1 *60 * 1000, 1000) {
public void onTick(long millisUntilFinished) {
//Some code
Log.v(Constants.TAG, "Service Started");
}
public void onFinish() {
Log.v(Constants.TAG, "Call Logout by Service");
// Code for Logout
stopSelf();
}
};
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
And then Add the below code in every activity.
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
LogoutService.timer.start();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
LogoutService.timer.cancel();
}