getSystemService from non Activity class - android

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()

Related

How to acces getSystemService in Application class

I want to access the TELEPHONY_SERVICE system service in the Application class, but my app crashes when I run it.
public class SimpleDhtApplication extends Application {
TelephonyManager tel = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String portStr = tel.getLine1Number().substring(tel.getLine1Number().length() -4);
final String myPort = String.valueOf((Integer.parseInt(portStr) * 2));
}
I think I am not accessing the context correctly, can somebody help!
Override the onCreate method of the Application class first. Within the onCreate, put the code you have so it would look like:
public class SimpleDhtApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
TelephonyManager tel = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String portStr = tel.getLine1Number().substring(tel.getLine1Number().length() -4);
final String myPort = String.valueOf((Integer.parseInt(portStr) * 2));
}
}
Update: Watch out for tel.getLine1Number(); it may return null as explained here.

getSharedPreferences() is not recognized in the class extended from BroadcastReceiver

I like to use SharedPreferences in the class extended from BroadcastReceiver. But this method getSharedPreferences(prefName, MODE_PRIVATE); is not recognized. How can I retrieve SharedPreferences in the BroadcastReceiver class?
Thanks
you need a Context to retrieve the SharedPreferences. onReceive gives you the context
getSharedPreferences is a method of Context, your activity extends Context that is why you can use it as is.
If you want to use it somewhere else, you need a context. The easiest way is provided in this answer
Static way to get 'Context' on Android?
Step 1 : You add a class in AndroidManifest.xml
Step 2 : You create your class this way
public class App extends Application{
private static Context _context;
#Override
public void onCreate() {
super.onCreate();
_context = this;
}
public static Context getContext(){
return _context;
}
}
Step 3 : Whenever you need something with a context you do : App.getContext()
in your case App.getContext().getSharedPreferences()

How to reference the current or main activity from another class

I often find myself needing to access methods that require referencing some activity. For example, to use getWindowManager, I need to access some Activity. But often my code for using these methods is in some other class that has no reference to an activity. Up until now, I've either stored a reference to the main activity or passed the context of some activity to the class. Is there some better way to do this?
If you already have a valid context, just use this:
Activity activity = (Activity) context;
Passing context is better way for refrence Activity.
You can pass Context to another class.
IN Activity ::
AnotherClass Obj = new AnotherClass(this);
IN Another Class
class AnotherClass{
public AnotherClass(Context Context){
}
}
You can implement the necessary methods in your activity and implement a Handler. Then, simply pass a handler instance to your classes, where you can obtain a message for handler and send it to target.
You can make you application instance a singleton, and use it when you need a Context
An example is in this question:
Android Application as Singleton
This way, when you need a Context, you can get it with
Context context = MyApplication.getInstance()
This might not be the cleanest solution, but it has worked well for me so far
I found a way to get the Activity to a non-activity class that I have not seen discussed in forums. This was after numerous failed attempts at using getApplicationContext() and of passing the context in as a parameter to constructors, none of which gave Activity. I saw that my adapters were casting the incoming context to Activity so I made the same cast to my non-activity class constructors:
public class HandleDropdown extends Application{
...
public Activity activity;
...
public HandleDropdown() {
super();
}
public HandleDropdown(Activity context) {
this.activity = context;
this.context = context;
}
public void DropList(View v,Activity context) {
this.activity = context;
this.context = context;
...
}
After doing this cast conversion of Context to Activity I could use this.activity wherever I needed an Activity context.
I'm new to android so my suggestion may look guffy but what if you'll just create a reference to your activity as private property and assign that in OnCreate method? You can even create your CustomActivity with OnCreate like that and derive all your activities from your CustomActivity, not the generic Activity provided by android.
class blah extends Activity{
private Activity activityReference;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityReference = this;
}
}
after that you could use that the way you want, i.e. in
Intent i = new Intent(activityReference, SomeOtherActivity.class)
etc
There are many ways for Activities communication.
you can use:
the startActivityForResult method
a system of broadcast message and receiver (you can broadcast an event from the actual activity, and register a receiver in the target activity. Remember that the target activity must be previously initialized and non finished)
as you say, store a reference of the target activity wherever you need.
We built a framework for this. We have a BaseActivity class that inherits from Activity and it overrides all the lifecycle methods and has some static (class) variables that keep track of the activity stack. If anything wants to know what the current activity is, it just calls a static method in BaseActivity that returns the activity on top of our privately-managed stack.
It is kinda hacky, but it works. I'm not sure I would recommend it though.
Handle the Intent in the class you want to do these methods, and send your information to it in a Bundle like so:
Intent i = new Intent("android.intent.action.MAIN");
i.setComponent(new ComponentName("com.my.pkg","com.my.pkg.myActivity"));
Bundle data = new Bundle();
i.putExtras(data);
startActivityForResult(i);
Then use an OnActivityResultListener to grab the new data.
I solved this by making a singleton class has an instance of the class below as a member.
public class InterActivityReferrer <T> {
HashMap<Integer, T> map;
ArrayList<Integer> reserve;
public InterActivityReferrer() {
map = new HashMap<>();
reserve = new ArrayList<>();
}
public synchronized int attach(T obj) {
int id;
if (reserve.isEmpty()) {
id = reserve.size();
}
else {
id = reserve.remove(reserve.size() - 1);
}
map.put(id, obj);
return id;
}
public synchronized T get(int id) {
return map.get(id);
}
public synchronized T detach(int id) {
T obj = map.remove(id);
if (obj != null) reserve.add(id);
return obj;
}
}
This class can get a T object and return a unique integer assigned to the object by attach(). Assigned integers will not collide with each other unless HashMap fails. Each assigned integer will be freed when its corresponding object is detached by detach(). Freed integers will be reused when a new object is attached.
And from a singleton class:
public class SomeSingleton {
...
private InterActivityReferrer<Activity> referrer = new InterActivityReferrer<>();
...
public InterActivityReferrer<Activity> getReferrer() {return referrer;}
}
And from an activity that needs to be referred:
...
int activityID = SomeSingleton.getInstance().getReferrer().attach(this);
...
Now with this, a unique integer corresponding to this activity instance is returned. And an integer can be delivered into another starting activity by using Intent and putExtra().
...
Intent i = new Intent(this, AnotherActivity.class);
i.putExtra("thisActivityID", activityID);
startActivityForResult(i, SOME_INTEGER);
...
And from the another activity:
...
id refereeID = getIntent().getIntExtra("thisActivityID", -1);
Activity referredActivity = SomeSingleton.getInstance().getReferrer().get(refereeID);
...
And finally the activity can be referred. And InterActivityReferrer can be used for any other class.
I hope this helps.
public static Activity getLaunchActivity()
{
final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
final Method methodApp = activityThreadClass.getMethod("currentApplication");
App = (Application) methodApp.invoke(null, (Object[]) null);
Intent launcherIntent = App.getPackageManager().getLaunchIntentForPackage(App.getPackageName());
launchActivityInfo = launcherIntent.resolveActivityInfo(App.getPackageManager(), 0);
Class<?> clazz;
try
{
clazz = Class.forName(launchActivityInfo.name);
if(clazz != null)
return Activity.class.cast(clazz.newInstance());
}
catch (Exception e)
{}
return null;
}
Just a guess since I haven't done this but it might work.
1) Get your applicationContext by making your Android Application class a Singleton.
2) Get your ActivityManager class from the context.
3) Get a list of RunningTaskInfos using getRunningTasks() on the ActivityManager.
4) Get the first RunningTaskInfo element from the list which should be the most recent task launched.
5) Call topActivity on that RunningTaskInfo which should return you the top activity on the activity stack for that task.
Now, this seems like a LOT more work than any of the other methods mentioned here, but you can probably encapsulate this in a static class and just call it whenever. It seems like it might be the only way to get the top activity on the stack without adding references to the activities.

how to getSystemService within a ContentProvider in android?

I have class structure like this:
public class DHTContentProvider extends ContentProvider {
private Networking networking = new Networking();
public boolean onCreate() {
networking.init();
}
public class Networking extends Service {
public void init() {
TelephonyManager tel = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
}
}
}
Networking is a subclass of DHTContentProvider.
When I run it always NullPointerException. Anyone has idea?
Call getContext() to retrieve a Context, then call getSystemService() on that Context.
Maybe you should delete them "Context.".

ApplicationInfo on Android in static method

Not that complicated of a question today:
Is there a way to get the ApplicationInfo in a static method?
No.
To get to ApplicationInfo you need instance of Context, which you get via and instance of Application or Activity.
So, normally you'd do:
ApplicationInfo appIngo = this.getPackageManager().getApplicationInfo("your.app.package.name", GET_META_DATA)
where this is and instance of Context, either Activity, Service or Application.
You can inherit your your application class from Application
public class TestApplication extends Application
create private static instance variable inside this class
private static TestApplication instance = null;
instantiate it in onCreate method:
instance = this;
write access method
public static TestApplication getInstance() {
return instance;
}
From any place you can call
TestApplication.getInstance().getApplicationInfo()
Same way you can get ApplicationContext.

Categories

Resources