Two Listeners in Service (android) - android

Firstly,sorry my English.And i am sorry about a large text.I just tried to describe in details.
A bit of my story:
I am new in Android.I have some programming background(some Python,
some C++).I read a book about Java, at First.Then I read a book
about Android(just a few pages =) )
So,the goal of my program:
Run in background(here i used Service) PhoneCallListener. When there is an incoming call, i use SensorEventListener, and do some magical things.
How I realized it:
...
public class mbackground extends Service{
public int onStartCommand(Intent intent, int flags, int startId){
PhoneStateListener phoneStateListener = new PhoneStateListener();
TelephonyManager telephonyManager = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(phoneStateListener,PhoneStateListener.LISTEN_CALL_STATE);
then i try to use here "public class phoneCallListener extends PhoneStateListener{"
And some methods of PhoneStateListener
public void onCallStateChanged(int state, String incomingNumber){ do some things }
Here i have a problem: for some reason, the compiler does not like public in definition class phoneCallListener...And then,how i can use Sensor Listener in one of the methods of PhoneStateListener?
I tried to find information in Google. Honestly.
I do not know how to use Listeners correctly in that situation.I found some similar questions, but there Listeners used without class extends and some abstract methods.
Thanks for reading!

In onStartCommand
PhoneStateListener phoneStateListener = new PhoneStateListener();
should be
phoneCallListener phoneStateListener = new phoneCallListener();

Related

How should ActivityRetainedLifecycle.OnClearedListener be used?

I'm injecting an #ActivityRetainedScoped component via Hilt. The component is registering a listener so I want to make sure it cleans up after itself and doesn't leak anything.
I have seen ActivityRetainedLifecycle.OnClearedListener in the JavaDocs for Hilt but haven't seen any examples of how to use it.
E.g. using WifiManager as an example, at the moment I'm doing this:
#ActivityRetainedScoped
public class Wifi {
#Inject
public Wifi(
#NonNull final Application application,
#NonNull final ActivityRetainedLifecycle activityRetainedLifecycle,
#NonNull final WifiManager wifiManager
) {
final Context applicationContext = application.getApplicationContext();
final IntentFilter intentFilter = /* Init intentFilter */
final WifiScanReceiver wifiScanReceiver = /* Init wifiScanReceiver */
applicationContext.registerReceiver(wifiScanReceiver, intentFilter);
activityRetainedLifecycle.addOnClearedListener(() -> {
applicationContext.unregisterReceiver(wifiScanReceiver);
});
}
}
It feels self-explanatory but I've been burned by assuming stuff like this before and can't find much online to validate my assumption on it.
Is that the correct way to 'tear down' an activity-retained component that has external dependencies to make sure it doesn't leak?
Yes, according to the documentation.
And Thanks! I found it thanks to your question.
Interestingly it also explains the mechanics of it
Specifically this will be invoked during Activity.onDestroy() when Activity.isChangingConfigurations() is false.

getSystemService from non Activity class

I need to get LAC and Cid codes in my Android application. However, I need to do it inside a not-Activity class. The code I found is this:
TelephonyManager telephonyManager =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation cellLocation = (GsmCellLocation) telephonyManager.getCellLocation();
int cid = cellLocation.getCid();
int lac = cellLocation.getLac();
However, the method setSystemService is present only in Activity classes, and I have not found something to send "some sort of activity" to the class.
Is there any way of do so, without activity ?
You can pass context as an argument to constructor of the class. Inside the constructor you can initialize the TelephonyManager.
Example :
In class,
public class MyClass {
private TelephonyManager mTelephonyManager;
public MyClass(Context context) {
mTelephonyManager =(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
}
}
In Activity,
public class MyActivity extends Activity {
....
//Initializing class
MyClass myClass = new MyClass(this);
..
You just need to pass a Context object to call getSystemService() from it. You can also use an Activity object as Activity extends Context.
Then just call context.getSystemService()

Can I use a callback method from a BroadcastReceiver?

Learning to use the BroadcastReceiver class in Android, I have written a small program to receive the battery charge state and write it to three TextView fields in an activity.
However, I have made the BroadcastReceiver as a separate class to make it more simple and separate from the activity. Therefore I have to find a method to tell my Activity class that the battery data has been updated, or, which is my solution, to pass in references to the TextView fields from the Activity to the BroadcastReceiver class.
Does anyone know whether it is possible to make a callback method from the BroadcastReceiver to start a function, f.ex. updateTextViews(); in the Activity?
Here is the source code - note there are two java files:
http://pastebin.com/qjCTsSuH
Regards, Niels.
What worked a charm for me is simply declaring the interface objects as static. Bear in mind though that statics can cause as many problems as they solve as statics persist therir values accross instances.
public class MainActivity extends AppCompatActivity implements SocketMessageReceiver.ISocketMessageReceiver {
//Declare the cb interface static in your activity
private static SocketMessageReceiver.ISocketMessageReceiver iSocketMessageReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//Assign this
iSocketMessageReceiver = this;
socketMessageReceiver.registerCallback(iSocketMessageReceiver);
}
#Override
public void sendSocketMessage(String socketMessage) {
lblEchoMessage.setText(socketMessage);
}
}
And in your Receiver ....
public class SocketMessageReceiver extends BroadcastReceiver {
interface ISocketMessageReceiver {
void sendSocketMessage(String socketMessage);
}
//Also declare the interface in your BroadcastReceiver as static
private static ISocketMessageReceiver iSocketMessageReceiver;
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("com.WarwickWestonWright.SocketExample.RECEIVE")) {
iSocketMessageReceiver.sendSocketMessage(intent.getBundleExtra("DATA").getString("DATA"));
}
}
public void registerCallback(ISocketMessageReceiver iSocketMessageReceiver) {
this.iSocketMessageReceiver = iSocketMessageReceiver;
}
}
I have made the BroadcastReceiver as a separate class to make it more simple
IMHO, you made it more complex.
Therefore I have to find a method to tell my Activity class that the battery data has been updated, or, which is my solution, to pass in references to the TextView fields from the Activity to the BroadcastReceiver class.
Option #1: Just go back to using an inner class for the BroadcastReceiver. ACTION_BATTERY_CHANGED can only be used via registerReceiver() anyway. Just have onReceive() call some method on the activity to do the work of updating the UI.
Option #2: Pass your activity into the constructor of the BroadcastReceiver, and call the method as in option #1.
Option #3: Use an event bus, like Square's Otto or greenrobot's EventBus.

Properly Using Android Listeners

I'm new to Android programming and while I have successfully logged the output of a listener for a state change in the Telephony API, I'm having trouble accessing the value and writing it to a database. I can write to the log from within the inner class but can't save to DB as I can't access the helper from within the inner class. I'm also having trouble calling getSignalStrengths() method. these are all learning exercises and any advice would be much appreciated.
public class MyPhoneStateListener extends PhoneStateListener {
String sSstr = "initial value";
public String getSignalStrengths(){
return sSstr;
}
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
sSstr = signalStrength.toString();
Log.v("Test", sSstr);
}
}
You can access your database inside the MyPhoneStateListener in a couple of way
Create a MyPhoneStateListener constructor with a Context parameter and use this context to instantiate your database class.
Just instantiate your database class using
MyDatabase db = new MyDatabase(MainActivity.this)

Signal Strength on android saved as a variable

I'm trying to creat an app that would save the current signal strength. So far I've seen many examples that are all extending PhoneStateListener, but all of them use a Toast to display this information, like in this example:
http://www.firstdroid.com/2010/05/12/get-provider-gsm-signal-strength/
I was wondering a couple of things:
a) Do I always have to use the PhoneStateListener AND override the onSignalStrengthsChanged(SignalStrength signalStrength) ?
b) How can I access the value signalStrength.getGsmSignalStrength() from outside the PhoneStateListener class?
Thanks in advance
U can try with it. I cant say its the final solution.If u want to access certain data from other activity, then try it with shared preference.Shared preference value is visible from other activities
I might be late to answer your question, but if you are still looking for the answer, here it is:
a) yes you have to use the PhoneStateListener and override the onSignalStrengthsChanged as, in my knowledge that is the only way to get current cells' signal strength for GSM. The listener is only called in big signal strength changes, so you yourself cannot control the listener. the listener will automatically update or make a toast when it is called. So, it is better to declare the listener and ask it to listen at onCreate().
b) For accessing the the RSSI value from outside the Listener is not really difficult, just store the value in a variable and make a method like getRSSI(), which will return you the value when its called. The example is given below:
public class GsmRSSI extends Activity{
MyPhoneStateListener MyListener;
TelephonyManager Tel;
ArrayList<String> signalStrength = new ArrayList<String>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyListener = new MyPhoneStateListener();
Tel = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Tel.listen(MyListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
timer.schedule(new TimerTask() {
public void run() {
String rssi = MyListener.getStrength();
if(!rssi.equals(""))
signalStrength.add(rssi);
}
}, 0, 5000);//it will add the rssi value after every 5000ms
}
private class MyPhoneStateListener extends PhoneStateListener {
String gsmStrength = "";
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
gsmStrength = String.valueOf(signalStrength.getGsmSignalStrength()* 2 - 113);
}
public String getStrength() {
return gsmStrength;
}
}
}
This should do the work for you. But at the begining you might not get any rssi value for a little while as the listener is only called when there is a significant change in the rssi.

Categories

Resources