Programming functionality for an android app widget - android

I have a simple flashlight application and I would like to have the light switch on-off functionality by simply clicking on the widget also.
Now when I click on the widget my program starts, it is ok but it would be better to reach the functionality of my app directly from the widget.
I think now the appwidgetprowider just starts my activity:
Intent intent = new Intent(context, MainActivity.class);
In my flashlight`s main activity I switch on the led of the phone by the
switchOnTheFlash()
method.
Does anyone have an idea, how could I start this method from the widget?
Thank you and best regards!

Intent is not needed to turn on the flashlight as it will always take you somewhere in activities or actions. The simplest thing to do is make your switchOnTheFlash() function static like this -
public static void switchOnTheFlash() {
// Your Function
}
and Now you can call this function from any activity just like -
YourACtivity.switchOnTheFlash();
If Errors Occur --
Make sure that all the variables you use in switchOnTheFlash() should be static too or you will be getting error like cannot use non-static variables in static function (or may be somewhat written a bit different).
Another error, if you use functions like getResources() you can get errors. To get rid, Just make a static Context mContext; globally and initialize it like mContext = this; in OnCreate. Then simply replace mContext.getResources()... everywhere in your function switchOnTheFlash().
Cheers!

Related

Passing a activity context into a static method, memory leak potential?

I've seen this particular technique for launching activities and it seems to me like a bad idea because of static contexts but I was hoping someone might have a legit reason behind this approach.
The activity you want to launch implements a static launch(Context context) method that sets up the intent, flags, etc and finally starts the activity.
public static void launch(Context context){
Intent i = new Intent(context, SomeOtherActivity.class);
// flag stuff
context.startActivity(i);
}
Then a DifferentActivity could go and launch SomeOtherActivity with one line.
SomeOtherActivity.launch(DifferentActivity.this);
I like how it allows you to setup the flags in the activity away from the DifferentActivity that is launching it but it doesnt seem like a good enough reason to rationalize passing that activity's context into a static method.
Wouldn't this cause DifferentActivity to not be garbage collected because now that static method has a reference to it? This seems like a memory leak to me and probably not a good idea to do just to be able to keep the flags contained in the activity that is being created.
Is there something I'm missing here that makes this a good practice to do?
Passing something into a static function isn't a potential memory leak. Storing a variable in a static variable is. This technique is perfectly safe. Its one I'd even recommend, as you can pass in variables to the function and store them in extras inside the class that is going to use those extras, reducing the number of places that need to know of their existence and how they're laid out

Android Intent Activity Callback

I'm developing an Android module that basically consists of a custom View third parties can just drop into any of their activities.
This module includes a configuration activity (based on PreferenceActivity).
Given that you can't start an activity from a View, the module calls 'openConfig(Intent intent)' on the activity it is displayed in. This activity acts as a delegate for the module.
That works fine thus far (though I'd really like the module to handle everything internally, no delegate methods required, but I reckon that just isn't possible).
However, I need some sort of callback from the preference activity to the module, so that the module will get notified when the settings have been changed.
I was thinking of just adding the module's main class as a delegate to the preference activity;
ConfigActivity a = new ConfigActivity();
a.testVar = "testtest";
Intent intent = new Intent(getContext(), a.getClass());
delegate.handleConfigAction(intent); //
However, this test with just a simple String (instead of an interface) showed, that the String wouldn't get set after the activity has been started.
Second thought was to use 'putExtra()' on the intent, but that doesn't really suit the use case as the delegate I'd like to put there really is a View and not a serializable data object.
Are there any ways for me to handle this internally? I am aware of the 'onActivityResult()' function (http://developer.android.com/training/basics/intents/result.html), but that would mean that the third party developer using my module would need to handle this, something that needs to be avoided for obvious reasons.
Any help would be highly appreciated!
EDIT: FINAL SOLUTION
In the end I've changed the module from View to Fragment, which now works much better with handling "child" activities and such. When starting an Activity from a Fragment, the 'onActivityResult' function works beautifully to accomplish the task at hand.
You can start an Activity from a View using its Context as in:
#Override
public void onClick() {
Intent intent = new Intent(getContext(), ConfigActivity.class);
intent.putExtra("testVar", "testtest");
getContext().startActivity(intent);
}
You could use the onWindowVisibilityChanged() method to read the configuration that would be set in the ConfigActivity to make your View change its behavior.

Determine what Context variable to use in MediaPlayer.create in Android

Knotty problem with MP3 stream MediaPlayer in Android. I've done yet some app with it, but now I refactor the code cause of some reasons.
There is a call of a Service in the activity of Player:
mp3Service.playSong(getBaseContext(),url);
The playSong method consists of this:
public void playSong(Context c, String url) {
if (this.currenturl.equals(""))
{
this.mplayer = MediaPlayer.create(c, Uri.parse(url));
this.currenturl=url;
this.mplayer.start();
}
else
{
if (!this.currenturl.equals(url))
{
this.mplayer.stop();
//this.mplayer=null;
this.mplayer = MediaPlayer.create(c, Uri.parse(url));
this.mplayer.start();
this.currenturl=url;
} else
{
if (this.on==false)
this.mplayer.start();
};
};
this.on=true;
}
The call to playSong method worked normally when it was on the ImageView click listener! The music started to play.
But, when calling simply from player activity onCreate - it stops the app.
Not sure why, but it's totally hard to understand what context parameter to use here.
I've read some similar articles and documentation, but there is much fog.
How to determine what should I use for the first Context parameter here?
Does it depend on from where I call the .playSong(Context, Uri)? If yes, how?
Context is very abstract for new in Android, the class documentation by itself don't shed light to it.
There are many choices which I tried but I need logical reason why to use this and how to determine why app stops.
getApplicationContext()
getBaseContext()
this
PlayerActivity.this
and others. But without understanding it's not right. Maybe the error is in the other place.
But without the service call all was working.
I agree that Context and when to use which kind can be a hard idea to grasp. From what I have learned, it normally seems best to use your Activity's Context in most situations. These are my thoughts on it and somebody please correct me if I'm wrong with examples/facts.
How to determine what should I use for the first Context parameter here? Does it depend on from where I call the .playSong(Context, Uri)? If yes, how?
Yes and not necessarily. From what I have read, you want to use the Context that is closest to the Object that needs it...use the most minimal Context needed.
If you call if from an Activity and the Object will be destroyed when that Activity is destroyed then use the Activity Context (here Player.this).
If you are calling a service, which has its own Context then use the Service's Context.
If it needs access to things like System services then use getApplicationContext()
You said you've already read articles about using Context and since I don't know which ones I won't post a bunch of links. However,
Here is a good SO answer about using getApplicationContext()
Maybe the error is in the other place.
If you post what error you are getting then maybe we can help better to find the error

onActivityResult outside of an activity scope

I'm trying to create an android project that contains shared code which will be used by others.
In this project I only have POJO and no android specific classes.
Some of the functionality requires calling some activities and is depended on the result.
My POJO classes get reference to the calling activity when used, but that's happening at run time and I have no control over the implementation of those activities.
My problem is that with the reference of the calling activity I can startActivityForResult but I have no way of adding the onActivityResult, which might exists in the calling activity but is not aware of the requestCode I used.
My question then is how do I know, from within a regular java object when the activity has returned? since, as far as I understand I can only implement onActivityResult on Activity classes.
thanks!
You will have quite a few problems with this setup, but this is how you might want to get started:
You will have to include an activity in your project which does nothing else than starting the activity you want to get the result from and stores it in a globally accessible storage (e.g. a singleton or a static field).
class Pojo {
static final ConditionVariable gate = new ConditionVariable();
static int result;
int m(Context context) {
context.startActivity(new Intent(context, ForwarderActivity.class));
gate.block();
return result;
}
}
class ForwarderActivity extends Activity {
private boolean started = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!started) {
started = true;
startActivityForResult(new Intent("ContactsProvider"), 1);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Pojo.result = resultCode;
Pojo.gate.open();
}
}
There are a couple of problems, though. Like your POJO's method can't be called from the main (UI) thread, because you need to convert an asynchronous call (startActivityForResult()) to a synchronous one (Pojo.m()) and the activity you want to receive info from will be started on the main thread, so you can't block it in Pojo.m()...
Anyway, the code does not work, but you can see which way to go if you really have to stick with this setup. But you should really try to come up with some other means of fetching the data, like a content provider.
i have the same problem while i play with UNITY3D,the unity have it's own Activity(the unity player),i don't wanna edit it for some reason. but the player activity do nothing inside the "onActivityResult" function. And i have something to do when access image picker,i can call "unityPlayer.startActivityForResult" to open image picker,but NO WAY TO CODE MY OWN "onActivityResult".
i think what we hope is something like this:
OtherActivityClass.onActivityResultListener=function(){My Own CODE}..........OR
OtherActivityClass.onActivityResultListener.add(myResultListener)..................
My question then is how do I know, from within a regular java object when the activity has returned?
Have the activity call the POJO, supplying the result.
My POJO classes get reference to the calling activity when used, but that's happening at run time and I have no control over the implementation of those activities.
Then whoever is in "control over the implementation of those activities" will need to have the activity call the POJO, supplying the result. This is no different than any other callback/listener mechanism.
Maybe PendingIntent http://developer.android.com/reference/android/app/PendingIntent.html can help you with that. I'm still looking around for a solution to my problem and for me, this class looks quite promising.
Another way might be to make your own class abstract and have a method onActivityResult that is required to be overridden. Of course, you would have to rely on JavaDoc and "please call super.onActivityResult" to be able to process the result in your code. But if the users of your class want to have some success with your code they should follow your JavaDoc instructions.
Similar to what Szabolcs Berecz suggests, it is possible. There is no beautiful solution, but following is possible:
create a simple no view activity that starts the intent for you
distribute the result through a global listener manager where interested classes can register and unregister theirself (the POJO e.g.)
this is non blocking but startActivityForResult and waiting for its result is non blocking in general
I've set this up in a library for app settings and some settings do start a system intent (e.g. select an image) and need to wait for their result and this works even after screen rotation without the need of any code adjustments by the libraries user.

Access Activity in a static way

I have an activity which has a static method for updating a textfield. This way I can update this view from another activity.
But now I'm trying to get a Context variable in this static method which is not possible. I've tried declaring a Context variable and initialising it in onCreate ( context = getApplicationContext();)
But still I can't access context in this static method. How is this normally done?
edit: a little bit more information about my situation. I'm starting a countdowntimer in an activity(a) which updates another activity's(b) ``textfield every second. And it does this by accessing b's setTextField in a static way..
How is this normally done?
Accessing a TextView via a static method is not the best way to update the field from another activity. If you want to pass a value to the activity when it starts, you can send data via the intent (i.e. intent.getExtras). If you want to pass data back from a sub-activity, you can use startActivityForResult.
The way you are going is very strange. Why are you trying to change one activity content from another? May be you need to use startActivityForResult to strat a new activity and then return result from it and change views depending on it?
You might want to check some documentation on OO and using static functions. It is not considered a very good approach.
But as we are not talking about a better complete sollution: you can add a parameter with a context to the function, and just give it when you call the function :)
I would suggest the LocalBinder pattern to update the other Activity:
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html
Can you do something like this?
something like this <viewobj>.getContext()
Ref: How can I start an Activity from a non-Activity class?
Whenever you're busy with Activity A, there's no point in updating something on Activity B as it is simply not shown to the user at that point in time.
Seems to me you need to have some kind of global variable here that can be picked up in the onResume of Activity B.
Checkout this question : How to declare global variables in Android?
It shows you how to use the Application class to maintain global application state, accessable from all activities when needed.

Categories

Resources