Accessing an activity through a service - java

I have an Activity and a service.
The activity has a TextView member and a setText() method.
I would like to call that method through the Service, how can I do that?
Here is the code:
Activity:
public class MainActivity extends Activity {
private TextView tv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.tv1 = (TextView) findViewById(R.id.textView1);
Intent intent = new Intent(this,MyService.class);
startService(intent);
}
// <-- some deleted methods.. -->
public void setText(String st) {
this.tv1.setText(st);
}
}
Service:
public class MyService extends Service {
private Timer timer;
private int counter;
public void onCreate() {
super.onCreate();
this.timer = new Timer();
this.counter = 0;
startService();
}
private void startService() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
//MainActivityInstance.setText(MyService.this.counter); somthing like that
MyService.this.counter++;
if(counter == 1000)
timer.cancel();
}
},0,100);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}

You can use an intent in order to send any information (i.e. the counter for TextView member) to the Activity.
public void run() {
//MainActivityInstance.setText(MyService.this.counter); somthing like that
MyService.this.counter++;
Intent intentBroadcast = new Intent("MainActivity");
intentBroadcast.putExtra("counter",MyService.this.counter);
sendBroadcast(intentBroadcast);
if(counter == 1000)
timer.cancel();
}
...then, you will receive your data in the Activity using a Broadcast Receiver
/**
* Declares Broadcast Reciver for recive location from Location Service
*/
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get data from intent
serviceCounter = intent.getIntExtra("counter", 0);
// Change TextView
setText(String.valueOf(counterService));
}
};

Related

Call a Function in a OnPreferenceClickListener

I am trying to call a function in a OnPreferenceClickListener which is defined in a another class. Since I have not managed to initialisation an interface in OnPreferenceClickListener. I have given an example code below:
public void onCreatePreferences(Bundle bundle, String s) {
ListPreference preference = findPreference(getString(R.string.settings_ble_choose_device_key));
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(#NonNull Preference preference) {
callFunctionInMainActivity();
return false;
}
});
}
How i can call a function witch is implement in a another class?
Thank you very much
Rene
You can implement an intent for this. Where you send a broadcast from your OnPreferenceClickListener class and implement a broadcast received in the other class to listen for this intent and invoke the method that you want. Here is an example:
public void onCreatePreferences(Bundle bundle, String s) {
ListPreference preference = findPreference(getString(R.string.settings_ble_choose_device_key));
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(#NonNull Preference preference) {
sendBroadcast(new Intent(Constants.ACTION_STOP_MAIN_SERVICE));
return true;
}
});
}
In your other class:
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action= intent.getAction();
if(action.equalsIgnoreCase(ConstantesIdentifiant.ACTION_STOP_MAIN_SERVICE)){
finishAffinity();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(broadcastReceiver, new IntentFilter(ConstantesIdentifiant.ACTION_STOP_MAIN_SERVICE));
}
#Override
protected void onDestroy() {
unbindService(mConnection);
unregisterReceiver(broadcastReceiver);
super.onDestroy();
}

Calling a method immediately after starting intent in android?

Starting Intent then calling Method?
In the two classes, the second one has a StartIntent. Right now it simply starts the intent to the first class. I am wanting to know if it is possible from that same onClickListener to essentially StartIntent for the first class as usual, but then immediately call the defaultMap() method within it.
Sometimes I want to simply start the intent normally, and other times I want to start the intent and then call that method. 1) therefore, I can't just make so that OnCreate of the first class it calls defaultMap, because i don't always want to call it. But also 2) I don't want to JUST call the defaultMap() class. I need to call the full class so that it runs through the onCreate functions THEN goes to the defaultMap
FIRST CLASS USED
public class Daily_Schedule extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_daily__schedule);
......
.......
......
}
public void defaultMap(){
......
.......
......
}
SECOND CLASS USED
public class InRouteDisplay extends AppCompatActivity implements OnMapReadyCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_in_route_display);
home.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(InRouteDisplay.this, DailySchedule.class);
InRouteDisplay.this.startActivity(myIntent);
}
});
.....
....
.....
}
Try the following: Two ways: 1) Using putExtra() -------- 2) Using SharedPreferences
1)
Demo4.class:-----------
public class Demo4 extends AppCompatActivity {
private Button b;
private final String CALL_DEFAULT_MAP = "call_default_map";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_daily__schedule);
if(getIntent() != null) {//1
if(getIntent().getStringExtra(CALL_DEFAULT_MAP) != null) {
if (getIntent().getStringExtra(CALL_DEFAULT_MAP).equals("true")) {
defaultMap();
}
}
}
b = (Button) findViewById(R.id.b);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(Demo4.this, Demo5.class);
finish();
startActivity(myIntent);
}
});
}
public void defaultMap() {
Toast.makeText(getApplicationContext(),"defaultMap()---called",Toast.LENGTH_LONG).show();
}
}
Demo5.class------
public class Demo5 extends AppCompatActivity {
private Button home;
private final String CALL_DEFAULT_MAP = "call_default_map";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_in_route_display);
home = (Button) findViewById(R.id.home);
home.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(Demo5.this, Demo4.class);
myIntent.putExtra(CALL_DEFAULT_MAP,"true");//1
finish();
startActivity(myIntent);
}
});
}
}
2)
Demo4.class---------
public class Demo4 extends AppCompatActivity {
private Button b;
private final String CALL_DEFAULT_MAP = "call_default_map";
private SharedPreferences p;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_daily__schedule);
p = getApplicationContext().getSharedPreferences("p_key",
0);//2
if(p != null){//2
if(p.getBoolean(CALL_DEFAULT_MAP , false)){
defaultMap();
}
}
b = (Button) findViewById(R.id.b);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(Demo4.this, Demo5.class);
finish();
startActivity(myIntent);
}
});
}
public void defaultMap() {
setBoolean(CALL_DEFAULT_MAP , false);//2
Toast.makeText(getApplicationContext(),"defaultMap()---called",Toast.LENGTH_LONG).show();
}
public void setBoolean(String Name, boolean value)
{
if(p != null){
SharedPreferences.Editor editor = p.edit();
editor.putBoolean(Name, value);
editor.apply();
}
}
}
Demo5.class:----------------
public class Demo5 extends AppCompatActivity {
private Button home;
private final String CALL_DEFAULT_MAP = "call_default_map";
private SharedPreferences p;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_in_route_display);
p = getApplicationContext().getSharedPreferences("p_key",
0);
home = (Button) findViewById(R.id.home);
home.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setBoolean(CALL_DEFAULT_MAP , true);//2
Intent myIntent = new Intent(Demo5.this, Demo4.class);
finish();
startActivity(myIntent);
}
});
}
public void setBoolean(String Name, boolean value)
{
if(p != null){
SharedPreferences.Editor editor = p.edit();
editor.putBoolean(Name, value);
editor.apply();
}
}
}
No. The sending class doesn't get an instance of the Activity to call it on. What you can do is set a parameter in the intent, USE_DEFAULT_MAP to 1. The activity you launch can look for that variable, and use that to know that it should call defaultMap.
Use if statement inside the Daily_Schedule activity and check the extra whether they are set or null. Use getIntent() method. check the answer of this
From InRouteDisplay activity pass the intent data using putextra before calling InRouteDisplay.this.startActivity(myIntent);
Use this link to how to putextra data to the intent
Use this link's answer to know how to putextra data to the intent

Can't create handler inside thread that has not called Looper.prepare() on locationManager in service

I is the first time I am working with the location manager and I always get the same error:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
This happens when i call .requestLocationUpdates on a locationManager. I don't know how can I put this in the Main UI thread. Here is the code of the service where the error occurs:
public class TrackerService extends Service {
private Context mContext;
private LocListener mlocListener;
private LocationManager mlocManager;
private final IBinder myBinder = new MyLocalBinder();
public void initiateTracking() {
this.mContext = getApplicationContext();
mlocManager = (LocationManager) this.mContext.getSystemService(Context.LOCATION_SERVICE);
mlocListener = new LocListener();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
public Boolean getGPSStatus(){
return mlocManager.isProviderEnabled(mlocManager.GPS_PROVIDER);
}
public Double[] getCurrentLocation(){
Double[] lonLat = new Double[]{mlocListener.getLon(), mlocListener.getLat()};
Log.d("DEBUG", "getCurrentLocation: " + lonLat);
return lonLat;
}
public class MyLocalBinder extends Binder {
public TrackerService getService() {
return TrackerService.this;
}
}
#Override
public IBinder onBind(Intent arg0) {
return myBinder;
}
#Override
public void onCreate()
{
isRunning = true;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
new Thread(new Runnable() {
#Override
public void run() {
initiateTracking();
}
}).start();
return Service.START_STICKY;
}
#Override
public void onDestroy() {
isRunning = false;
}
}
Here is how i start my service and then bind to it:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
startService(new Intent(this, TrackerService.class));
bindService(new Intent(MainActivity.this, TrackerService.class), myConnection, Context.BIND_AUTO_CREATE);
}
You can add the code to run on the main UI Thread like this:
runOnUiThread(new Runnable() {
#Override
public void run() {
//your code here
}
});

Updating RecyclerView with adapter.notifyDataSetChanged()

I've implemented a RecyclerView which has a user interface of a timer counting down. I created a BroadcastService class which creates a CountDownTimer and broadcasts the timer's contents in the onTick() method to my MainActivity, where I use a BroadCast receiever to update the UI.
My BroadcastReceiver is only receiving the initial value from the BroadcastService. I figured that's because I hadn't notified the recycler view's adapter that the data had changed. However, because of variable scope, I'm unable to access my adapter from my broadcast receiver.
Perhaps I have a fundamental lack of understanding of variable scope, but how can I access the adapter from
adapter = new DataAdapter(getApplicationContext(), data);
in my broadcast receiver class? Because right now it's not being recognized.
This is my class definition + onCreate()
public class Profile_Page extends ActionBarActivity implements DataAdapter.ClickListener {
private RecyclerView recyclerView;
public DataAdapter adapter;
private Context context;
String currentUser;
Data current = new Data();
final List<Data> data = new ArrayList<>();
public static String BROADCAST_ACTION =
"packagename.countdown_br";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCAST_ACTION);
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(br, filter);
startService(new Intent(this, Broadcast_Service.class));
setContentView(R.layout.activity_profile__page);
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseClass");
query.whereEqualTo("author", ParseUser.getCurrentUser());
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
if (e == null) {
for (ParseObject getData : list)
{
current.1= getData.getString("1");
current.2= getData.getString("2");
current.3= getData.getString("3");
current.4= getData.getString("4");
current.5= getData.getString("5");
data.add(current);
}
}
else {
}
adapter = new DataAdapter(getApplicationContext(), data);
recyclerView.setAdapter(adapter); //set recyclerView to this adapter
}
});
}
And here's my Broadcast Receiver code [which is also in MainActivity.java]
public BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent);
//HOW TO NOTIFY DATA SET CHANGE
}
};
public void updateGUI(Intent intent) {
if (intent.getExtras() != null) {
long millisUntilFinished = intent.getLongExtra("countdown", 0);
current.goalTimer = String.valueOf(intent.getExtras().getLong("countdown") / 1000);
}
}
And, if it is of any use, here's my Broadcast Service class:
public class Broadcast_Service extends Service {
private final static String TAG = "BroadcastService";
LocalBroadcastManager broadcastManager;
public static final String COUNTDOWN_BR = "packagename.countdown_br";
Intent bi = new Intent(COUNTDOWN_BR);
CountDownTimer cdt = null;
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Starting timer...");
cdt = new CountDownTimer(30000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
bi.putExtra("countdown", millisUntilFinished);
sendBroadcast(bi);
}
#Override
public void onFinish() {
Log.i(TAG, "Timer finished");
}
};
cdt.start();
}
#Override
public void onDestroy() {
cdt.cancel();
Log.i(TAG, "Timer cancelled");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
First of all, extend the BroadcastReciever class as follows:
public class MyReciever extends BroadcastReciever{
private Profile_Page activity;
public MyReciever(Profile_Page activity){
this.activity = activity;
}
#Override
public void onReceive(Context context, Intent intent) {
activity.updateGUI(intent);
}
}
Create a static instance of your activity and pass it to your receiver.
public class Profile_Page extends ActionBarActivity implements DataAdapter.ClickListener {
private static Profile_Page instance;
private MyReciever myReceiver;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
myReceiver = new MyReciever(instance);
...
}
public void updateGUI(Intent intent) {
...
}
}
Now you can access your adapter quite easily. Hope this helps.

how to extract the string value in Android services from an activity?

how to extract the string value in Android services from an activity?
My activity has a edit text, the entered string must be received in my services.
TempLaunch.java :
public class TempLaunch extends Activity {
private EditText text;
private Button okbtn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.templaunch);
addListenerOnButton();
}
public void addListenerOnButton() {
text = (EditText) findViewById(R.id.edittext_newid);
okbtn = (Button) findViewById(R.id.button_newid);
okbtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(TempLaunch.this, "In Temp launch class ",Toast.LENGTH_SHORT).show();
Toast.makeText(TempLaunch.this, text.getText(),Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
Toast.makeText(TempLaunch.this, "I am in Main activity class ",Toast.LENGTH_SHORT).show();
startActivity(intent);
}
});
Intent i = new Intent(this, MusicService.class);
i.putExtra("DD_URL", text.getText().toString());
//startActivity(i);
}
}
MusicService.java
public class MusicService extends Service {
#Override
public void onCreate() {
super.onCreate();
String url = null;
Intent intent = getIntent();
String id = intent.getStringExtra("DD_URL");
System.out.println("Rosh :" + id);
Toast.makeText(MusicService.this, "I am in Service:"+ id,Toast.LENGTH_SHORT).show();
...
Please help me out with this regard.
Thanks in advance
You may use sendBroadcast(intent); which will broadcast the EditText from your Activity A.
Then you need to call onReceive(Context context, Intent intent) within your Service class. This method is called when the BroadcastReceiver is receiving an Intent broadcast, in your case will be sent from Activity A.
private final BroadcastReceiver receiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
// Do something
}
};
//Register your receiver in onResume:
#Override
protected void onResume()
{
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction("SOME_ACTION");
registerReceiver(receiver, filter);
}
//Unregister the receiver in onPause:
#Override
protected void onPause()
{
super.onPause();
unregisterReceiver(receiver);
}

Categories

Resources