So I'm following this example in Android developers:
http://developer.android.com/training/run-background-service/create-service.html
Creating a background service with IntentService.
Note that we define the class RSSPullService in the first code example:
public class RSSPullService extends IntentService {
#Override
protected void onHandleIntent(Intent workIntent) {
// Gets data from the incoming Intent
String dataString = workIntent.getDataString();
...
// Do work here, based on the contents of dataString
...
}
}
In the following page, Reporting Work Status:
http://developer.android.com/training/run-background-service/report-status.html
I'm confused, are we defining the same class again to get the status?
public final class Constants {
...
// Defines a custom Intent action
public static final String BROADCAST_ACTION =
"com.example.android.threadsample.BROADCAST";
...
// Defines the key for the status "extra" in an Intent
public static final String EXTENDED_DATA_STATUS =
"com.example.android.threadsample.STATUS";
...
}
public class RSSPullService extends IntentService {
...
/*
* Creates a new Intent containing a Uri object
* BROADCAST_ACTION is a custom Intent action
*/
Intent localIntent =
new Intent(Constants.BROADCAST_ACTION)
// Puts the status into the Intent
.putExtra(Constants.EXTENDED_DATA_STATUS, status);
// Broadcasts the Intent to receivers in this app.
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
...
}
Dont get confused,
both the classes are same
First one is to show how we create a service extending IntentService
Then they gave a example to send data to this IntentService
At last they gave example to shows how the same IntentService is returning result back.
Second code is just another example they changed the content of old intent service class
That's two separate examples, no need to define it twice, just use one definition. The code from first example (creating Intent Service) is just merged with code from Reporting Work example.
Related
Now that the PROVIDERS_CHANGED intent-filter can't be set in the Manifest, I'm doing it dynamically.
However, I need to register/unregister the dynamically coded Receiver in multiple places.
Due to this, I am creating a "Helper" Class that contains a static method with the Receiver code.
MY ISSUE: I can't seem to figure out how to get the Context in order to register/unregister receiver.
Here is my current code:
public class GpsReceiverHelper {
public static void gpsReceiverCode() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.location.PROVIDERS_CHANGED");
final BroadcastReceiver gpsReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() != null &&
intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
// RECEIVER CODE HERE
}
}
};
this.registerReceiver(gpsReceiver, intentFilter);
// THIS IS WHERE I CAN'T GET A CONTEXT (USING "this" OR OTHERWISE)
}
}
MY QUESTIONS:
(A) - How can I go about retrieving a context here?
(B) - Is creating a helper class with a public static method the right way to be doing this?
How can I go about retrieving a context here?
Pass it in as a parameter (public static void gpsReceiverCode(Context context)).
I need to register/unregister the dynamically coded Receiver in multiple places
When your receiver was in the manifest, it was "registered" in one place. Hence, when you do it dynamically, you can register it in one place (e.g., custom Application subclass).
Is creating a helper class with a public static method the right way to be doing this?
Probably not, insofar as you probably should not be needing to use this code in 2+ places.
I am using the quickstart-android code provided by google but after many attempts I cam unable to find a context that is not returning null. The BarcodeScannerProcessor is not itself an Activity, so I have attempted to create an instance of the LivePreviewActivity and use that as the context in the intent, but it's null.
The goal is to once a valid barcode is recognized I want to open a new activity that allows a user to verify value and on the push of a button call a webservice to post the barcode to a database via API. I am having a hard time finding a valid context and the app is crashing when it trys to execute the Intent.
Starting at line 97-107:
https://github.com/jamiekeefer/quickstart-android/blob/master/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/java/barcodescanning/BarcodeScanningProcessor.java
for (int i = 0; i < barcodes.size(); ++i) {
FirebaseVisionBarcode barcode = barcodes.get(i);
BarcodeGraphic barcodeGraphic = new BarcodeGraphic(graphicOverlay, barcode);
graphicOverlay.add(barcodeGraphic);
System.out.println(barcode.getRawValue());
if (!barcode.getRawValue().equals("") ) {
System.out.println("Got the number:" + barcode.getRawValue() + " Context: " + mContext); //OLD SCHOOL DEBUG OUTPUT
//enter code to start activity
Intent intent = new Intent(mContext, SendScannedBarcode.class);
String message = scannedBarcode;
intent.putExtra(EXTRA_MESSAGE, message);
mContext.startActivity(intent);
}
}
You can back up in the repo to see the instance of the LivePreviewActivity where I trying to get context.
I have tried a number of things and read about Context, Views and Activities and basically have completely confused myself. The only tuts I can find are using Kotlin, which is not helping clarify things.
I appreacite any help in indentifying or contruting a valid Intent from this Context. Thank you.
So I am assuming that in your LivePreviewActivity you are creating an object of the class BarcodeScanningProcessor. What you can do is change the constructor in the BarcodeScanningProcessor class to accept a context and then you pass in your LivePreviewActivity's context.
This is what the code should look like:
In BarcodeScanningProcessor:
public BarcodeScanningProcessor(Context context) {
// Note that if you know which format of barcode your app is dealing with, detection will be
// faster to specify the supported barcode formats one by one, e.g.
// new FirebaseVisionBarcodeDetectorOptions.Builder()
// .setBarcodeFormats(FirebaseVisionBarcode.FORMAT_QR_CODE)
// .build();
detector = FirebaseVision.getInstance().getVisionBarcodeDetector();
this.mContext = context;
}
Then in LivePreviewActivity:
In the particular case of your activity you would do:
case BARCODE_DETECTION:
Log.i(TAG, "Using Barcode Detector Processor");
cameraSource.setMachineLearningFrameProcessor(new BarcodeScanningProcessor(getApplicationContext()));
break;
Or if you just wanted to create an object of the class you could do:
BarcodeScanningProcessor bsp = new BarcodeScanningProcessor(getApplicationContext());
This should now give your BarcodeScanningProcessor class the context of your activity. Now, in BarcodeScanningProcessor, mContext should not be null and will have the context of your activity. I hope this answers your question.
try this create Application class
import android.app.Application;
public class MyApplication extends Application {
static MyApplication instance;
#Override
public void onCreate() {
super.onCreate();
instance=this;
}
public static MyApplication getInstance() {
return instance;
}
}
Register in manifest file
<application
..
android:name="com.yourpackage.MyApplication"
..>
.
.
.
</application>
start activity using this MyApplication.
Intent intent = new Intent(MyApplication.getInstance(), SendScannedBarcode.class);
String message = scannedBarcode;
intent.putExtra(EXTRA_MESSAGE, message);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MyApplication. getInstance().startActivity(intent);
Another way of handling the issue is create new constructor of BarcodeScanningProcessor which takes interface call back and once processing is done pass back result to caller.
public interface BarcodeUpdateListener {
#UiThread
void onBarcodeDetected(Barcode barcode);
}
private BarcodeUpdateListener callback;
public BarcodeScanningProcessor(BarcodeUpdateListener callback){
this.callback = callback;
detector = FirebaseVision.getInstance().getVisionBarcodeDetector();
}
Once you get the result pass result to caller
callback.onBarcodeDetected(<Barcode>)
You can get the context from graphicOverlay:
Context context = graphicOverlay.getContext();
I made an application "Quiz", which has 4 activities. Main activity sends a String with your name from EditText to activity with first question. I have a problem here, because I don't know how to send this string immediately to final activity from main activity, but without going to final activity. I want to go to Activity with first question from main activity, then to activity with second question, and in the end I want to go to final activity.
Thanks for your help!
You could use static fields to pass data.
Inside your FinalActivity class you could add the following variable:
private static String NAME = "";
And with the following getters and setters:
public static String getName(){
return NAME;
}
public static void setName(String name){
NAME = name;
}
You can use the getter setter here at Application class so you can get the string data from anywhere were you want to. This is not the only way but i think it is also the easy way.
public class MyApplication extends Application {
private String someVariable;
public String getSomeVariable() {
return someVariable;
}
public void setSomeVariable(String someVariable) {
this.someVariable = someVariable;
}
}
add this in your manifest
<application
android:name=".MyApplication"
android:icon="#drawable/icon"
android:label="#string/app_name">
hen in your activities you can get and set the variable like so:
/ set
((MyApplication) this.getApplication()).setSomeVariable("foo");
// get
String s = ((MyApplication) this.getApplication()).getSomeVariable();
Some Url which may help you Android global variable
You can use shared preference also but as per our requirement i don't recommend that to you
Android Shared preferences example
You can use Broadcast Receiver for your requirement. In your activity from which you want to send data, do this way:
Intent intent = new Intent();
intent.setAction("fourthactivity");
sendBroadcast(intent);
And In your fourth activity, make a broadcast receiver which receive your intent :
public class IncomingReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("fourthactivity")) {
System.out.println("GOT THE INTENT");
}
}
}
Tell me if this doesn't work or click right if it works for you.
You can use SharedPreference to store the answers as you go from one activity to other and later compare all the answers in the FinalActivity in that way less complex coding and you will achieve your desired result.
Hey I am pretty new to making android apps and I understand that the easiest way to pass data between two activities is through an intent.
In one of my classes (EventOptions.java), I call this line of code:
Intent i = new Intent(EventOptions.this, PhotoFetcher.class);
i.putExtra("imageArray", imageIDs);
startActivity(i);
imageIDs is a string array
In my PhotoFetcher class, I want to set a string array called imageIDs to the imageIDs string array that I am passing through the intent.
I want to set images as a global variable in my class:
public class MainActivity extends Activity implements View.OnClickListener{
Intent it = getIntent();
String[] imageIDs = it.getStringArrayExtra("imageArray");
...
}
This crashes my app however. Is this not allowed? And if so, how can I fix it? Thanks in advance!
Need to call getIntent() in a method instead of at class level. call it inside onCreate :
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// get Intent here
Intent it = getIntent();
String[] imageIDs = it.getStringArrayExtra("imageArray");
}
if I want to use the imageIDs array in another public class defined
in my PhotoFetcher class, do I need to call it again?
To get imageIDsin PhotoFetcher class either declare String[] imageIDs as global variable or pass imageIDs using PhotoFetcher class constructor
You have to use putStringArrayListExtra. You can convert your String[] to an ArrayList first.
Like so
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(imageIDs));
Intent i = new Intent(EventOptions.this, PhotoFetcher.class);
i.putStringArrayListExtra("imageArray", arrayList);
startActivity(i);
And then you can fetch it like you do, preferably in onCreate or after that call.
Intent it = getIntent();
ArrayList<String> imageIDs = it.getStringArrayListExtra("imageArray");
Share data without persisting to disk
It is possible to share data between activities by saving it in memory given that, in most cases, both activities run in the same process.
Note: sometimes, when the user leaves your activity (without quitting it), Android may decide to kill your application. In such scenario, I have experienced cases in which android attempts to launch the last activity using the intent provided before the app was killed. In this cases, data stored in a singleton (either yours or Application) will be gone and bad things could happen. To avoid such cases, you either persist objects to disk or check data before using it to make sure its valid.
Use a singleton class
Have a class to whole the data:
public class DataHolder {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
private static final DataHolder holder = new DataHolder();
public static DataHolder getInstance() {return holder;}
}
From the launched activity:
String data = DataHolder.getInstance().getData();
Use application singleton (I would recommend this)
The application singleton is an instance of android.app.Application which is created when the app is launched. You can provide a custom one by extending Application:
import android.app.Application;
public class MyApplication extends Application {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
}
Before launching the activity:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
Then, from the launched activity:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
ρяσѕρєя K hit the nail on the head, you're running a method where constructors and fields go. To make the variables (the imageIDs) global, it's quite simple and there are a few ways of doing it. Declare them outside any method, and then assign them in your onCreate or onResume (which will always be called).
Try this:
public class MainActivity extends Activity implements View.OnClickListener {
//global variable
String[] imageIDs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get Intent here
Intent it = getIntent();
imageIDs = it.getStringArrayExtra("imageArray");
}
}
When considering the case with android activity, the first method to work is its onCreate method..right?
Suppose i want to pass 2 parameters to android activity class say UserHome . For that am creating the constructor of activity class UserHome and accepting the params.
But when we are calling an activity we are not initializing the Activity class, we are just creating an intent of UserHome class.
Then how can we pass params to that activity from another activity without using intent.putExtra("keyName", "somevalue"); usage.
Experts please clarify how we can cover a situation like this.?
Not sure why you would not want to use the intent params. That is what they are there for. If you need to pass the same parameters from different places in your application, you could consider using a static constructor that builds your intent request for you.
For example:
/**
* Sample activity for passing parameters through a static constructor
* #author Chase Colburn
*/
public class ParameterizedActivity extends Activity {
private static final String INTENT_KEY_PARAM_A = "ParamA";
private static final String INTENT_KEY_PARAM_B = "ParamB";
/**
* Static constructor for starting an activity with supplied parameters
* #param context
* #param paramA
* #param paramB
*/
public static void startActivity(Context context, String paramA, String paramB) {
// Build extras with passed in parameters
Bundle extras = new Bundle();
extras.putString(INTENT_KEY_PARAM_A, paramA);
extras.putString(INTENT_KEY_PARAM_B, paramB);
// Create and start intent for this activity
Intent intent = new Intent(context, ParameterizedActivity.class);
intent.putExtras(extras);
context.startActivity(intent);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Extract parameters
Bundle extras = getIntent().getExtras();
String paramA = extras.getString(INTENT_KEY_PARAM_A);
String paramB = extras.getString(INTENT_KEY_PARAM_B);
// Proceed as normal...
}
}
You can then launch your activity by calling:
ParameterizedActivity.startActivity(this, "First Parameter", "Second Parameter");
I can see one situation where you'd be unable to use the standard method of passing the parameters via the Intent: When you're creating an activity that will be launched by another app (say, the edit activity of a Tasker plugin) and, therefore, do not have control over the Intent that will launch your activity.
It's possible to create an Activity that accepts parameters in its constructor. The trick to using it, though, is not to use it directly, but to use a derived class with a default constructor that calls super() with the appropriate arguments, as such:
class BaseActivity extends Activity
{
public BaseActivity(String param1, int param2)
{
// Do something with param1 and param2.
}
// Many more lines of awesomeness.
}
class DerivedActivity extends BaseActivity
{
public DerivedActivity()
{
super("param1", 42);
}
}
Naturally, if you need to generate the parameters to pass to BaseActivity(), you can simply replace the hard-coded values with function calls.
We can pass the value from parent activity to child activity using the bundled collection and shared preference.
1. Shared Preference
2. Bundle Collection
Passing data or parameter to another Activity Android
But you also can create very well a constructor of UserHome.
public class MainActivity extends Activity {
UserHome userHome = new UserHome(param1,param2);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
userHome.yourMethod();
}}
Why do you think that is not possible to initialize a contructor?..MainActivity is a class like any other, just that extends Activity, but also keeps the properties of a class, so that can have, constructors, methods, members.