I have something strange going on with my application.
I am trying to send a string via Broadcast by doing the following:
1st step (Sending):
Intent intent = new Intent("INFO");
intent.putExtra("INFO_VALUE", "hello_world_2019");
2nd step (Receiving):
if ("INFO".equals(intent.getAction())) {
String abc = intent.getStringExtra("INFO_VALUE");
Log.i(TAG, "" + abc);
}
Doing the previous steps, I get a null into my abc field. Also, if I use the debugger and check my intent related to the second step, I get:
intent -> mExtras -> mMap -> value[0] -> name: "hello_world_2019"
I am confused to what is going on. The abc field is not supposed to be null, but it is in this case.
How can I populate the aforementioned field so it is not null ?
Please explain what exactly you are trying to do, if you want to send data from one activity to other than my friend this is not the correct way to do that.
If you want to send a broadcast and receive that somewhere inside your code than you need to follow the below steps:
ReceiverActivity.java
#Override
public void onCreate(Bundle savedInstanceState) {
...
// Register to receive messages.
// We are registering an observer (mMessageReceiver) to receive Intents
// with actions named "custom-event-name".
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("INFO"));
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
#Override
protected void onDestroy() {
// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
SenderActivity.java
private void sendMessage() {
Log.d("sender", "Broadcasting message");
Intent intent = new Intent("INFO");
// You can also include some extra data.
intent.putExtra("message", "Message goes here!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Related
So im getting my data from a web service and using RecyclerView adapter.In RecyclerView.adapter's onBindviewholder method I want to pass the data to the recyclerView in the MainActivity but also pass the data (item) to MyMapsActivity.The thing is the onBindViewholder has setOnClickListener and
setOnLongClickListener as controls that are being used. Is there either a way to send the data(item) using an intent that doesnt start the activity or is there a way I can wire up a new button within the onBindViewholder method because what happens is when the app starts up it goes straight to MyMapsActivity which is expected. Is there a way to control this by either using a new button that can interact with onBindViewholder or is there a way to pass the intent.putExtra without starting the MyMapsActivity.Maybe My understanding is flawed but here is my code for the methods and activities stated:
onBindViewholder
public void onBindViewHolder(DataItemAdapter.ViewHolder holder, int position) {
final DataItem item = mItems.get(position);
try {
holder.titletext.setText(item.getTitle());
holder.companyText.setText(item.getCompany());
holder.cityText.setText(item.getCity());
holder.salarytext.setText(""+ item.getSalary());
holder.descriptionText.setText(item.getDescription());
holder.responsibilityText.setText(item.getResponsibility());
holder.latText.setText(""+ item.getLatitude());
holder.lngText.setText(""+ item.getLongitude());
holder.phoneText.setText(item.getPhone());
holder.provinceText.setText(item.getProvince());
} catch (Exception e) {
e.printStackTrace();
}
//click
holder.mView.setOnClickListener(new View.OnClickListener() {//getting viewholder class and ctor
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext,DetailsActivity.class);
intent.putExtra(ITEM_KEY,item);
mContext.startActivity(intent);
}
});
//long click
holder.mView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Toast.makeText(mContext, "long click: " + item.getTitle(), Toast.LENGTH_SHORT).show();
return false;
}
});
// !!!!!----this is the intent Im talking about----!!!
Intent intent = new Intent(mContext,MyMapActivity.class);
intent.putExtra(ITEM_KEY,item);
mContext.startActivity(intent);
}
My maps method :
public void onMapReady(GoogleMap googleMap) {
final DataItem item = getIntent().getExtras()
.getParcelable(DataItemAdapter.ITEM_KEY); //--------gets intent frm dataItemAdapter
if (item == null) {
throw new AssertionError("null data recived");
}
mapReady = true;
mMap = googleMap;
LatLng latLngToronto = new LatLng(43.733092, -79.264254);
// LatLng latLnghome = new LatLng(43.656729, -79.377162);
CameraPosition target = CameraPosition.builder().target(latLngToronto).zoom(15).tilt(65).build();
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(target));
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
markerDisplay(item.getTitle(),item.getLatitude(),item.getLongitude());//------maps jobs marker-------new
//add markers and
//instantiate
// mMap.addMarker(mp);
// mMap.addMarker(md);
}
You do not need to call startAcivity method.
There is sendBroadcast method for sharing intent to other components.
String CUSTOM_ACTION = "com.example.YOUR_ACTION";
Intent i = new Intent();
i.setAction(CUSTOM_ACTION)
intent.putExtra(ITEM_KEY,item);
context.sendBroadcast(intent);
Then you can receive your intent with BroadcastReceiver
public class MyReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action!=null && action.equals(CUSTOM_ACTION)){
//do something
}
}
}
register receiver with custom IntentFilter into onCreate method of your activity
IntentFilter filter = new IntentFilter(CUSTOM_ACTION);
registerReceiver(myReceiver, filter);
And do not forget unregister it in onDestroy
unregisterReceiver(myReceiver);
P.S
There are many ways of transferring data between classes and components. It depends on your purpose.
Broadcast receiver with intents are good for data transfer between services and activities and for data transfer between apps.
If you need to have access to data from different places then there are other ways.
If the data needs to be stored on a disk, then the database is suitable.
To store data in RAM, you can use separate class and store this class as a Singleton or into your Application class.
I'm trying to develop a simple app, which receives text from other android Apps and then open a browser.
I have implemented it as described in the documentation here:
https://developer.android.com/training/sharing/receive.html
It works, but only once.
The first time a text is shared from an other App, the browser is opened correctly.
But the second time only my app is opened, but not the browser.
What could be the reason for this?
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the intent that started this activity
Intent intent = getIntent();
// Get the action of the intent
String action = intent.getAction();
// Get the type of intent (Text or Image)
String type = intent.getType();
// When Intent's action is 'ACTION+SEND' and Type is not null
if (Intent.ACTION_SEND.equals(action) && type != null) {
// When tyoe is 'text/plain'
if ("text/plain".equals(type)) {
handleSendText(intent); // Handle text being sent
}
}
}
private void handleSendText(Intent intent) {
// Get the text from intent
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
openBrowser(sharedText);
}
}
private void openBrowser(String text) {
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://example.com/api.php?text=" + text));
startActivity(browserIntent);
}
}
openBrowser method is called from the handleSendText method witch it is on the onCreate method , second time you open your app ( If you didnt press the back button ) your app is already created ! so the code will never execute.
Please check the life cycle of an android activity below
You may edit your code and call the openBrowser method on the onResume method or just make a button to call the method openBrowser Oncliking the button.
I'm wondering, is it possible to send information to the activity that I return to after calling finish()?
For example, I have an Activity SendMessageActivity.class which allows the user to post a message to their feed. Once that message has been saved to the server, I call finish(). Should I instead just start my MainActivity.class with a new Intent? Or is it better for life cycle development to just finish SendMessageActivity.class?
I don't see the point of starting a new activity since closing the current one will always bring you back to MainActivity.class. How can I just send a String extra after finishing the current Activity?
Use onActivityResult.
This might help you to understand onActivityResult.
By using startActivityForResult(Intent intent, int requestCode) you can start another Activity and then receive a result from that Activity in the onActivityResult() method.So onActivityResult() is from where you start the another Activity.
onActivityResult(int requestCode, int resultCode, Intent data) check the params here. request code is there to filter from where you got the result. so you can identify different data using their requestCodes!
Example
public class MainActivity extends Activity {
// Use a unique request code for each use case
private static final int REQUEST_CODE_EXAMPLE = 0x9988;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an Intent to start AnotherActivity
final Intent intent = new Intent(this, AnotherActivity.class);
// Start AnotherActivity with the request code
startActivityForResult(intent, REQUEST_CODE_EXAMPLE);
}
//-------- When a result is returned from another Activity onActivityResult is called.--------- //
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// First we need to check if the requestCode matches the one we used.
if(requestCode == REQUEST_CODE_EXAMPLE) {
// The resultCode is set by the AnotherActivity
// By convention RESULT_OK means that what ever
// AnotherActivity did was successful
if(resultCode == Activity.RESULT_OK) {
// Get the result from the returned Intent
final String result = data.getStringExtra(AnotherActivity.EXTRA_DATA);
// Use the data - in this case, display it in a Toast.
Toast.makeText(this, "Result: " + result, Toast.LENGTH_LONG).show();
} else {
// AnotherActivity was not successful. No data to retrieve.
}
}
}
}
AnotherActivity <- This the the one we use to send data to MainActivity
public class AnotherActivity extends Activity {
// Constant used to identify data sent between Activities.
public static final String EXTRA_DATA = "EXTRA_DATA";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another);
final View button = findViewById(R.id.button);
// When this button is clicked we want to return a result
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Create a new Intent as container for the result
final Intent data = new Intent();
// Add the required data to be returned to the MainActivity
data.putExtra(EXTRA_DATA, "Some interesting data!");
// Set the resultCode to Activity.RESULT_OK to
// indicate a success and attach the Intent
// which contains our result data
setResult(Activity.RESULT_OK, data);
// With finish() we close the AnotherActivity to
// return to MainActivity
finish();
}
});
}
#Override
public void onBackPressed() {
// When the user hits the back button set the resultCode
// to Activity.RESULT_CANCELED to indicate a failure
setResult(Activity.RESULT_CANCELED);
super.onBackPressed();
}
}
Note : Now check in MainActivity you startActivityForResult there you specify a REQUEST_CODE. Let's say you want to call three different Activities to get results.. so there are three startActivityForResult calls with three different REQUEST_CODE's. REQUEST_CODE is nothing but a unique key you specify in your activity to uniquely identify your startActivityForResult calls.
Once you receive data from those Activities you can check what is the REQUEST_CODE, then you know ah ha this result is from this Activity.
It's like you send mails to your lovers with a colorful covers and ask them to reply in the same covers. Then if you get a letter back from them, you know who sent that one for you. awww ;)
You can set result of an activity, which allow you to data into an initent.
In your first activity, call the new one with startActivityForResult() and retrieve data in method onActivityResult. Everything is in documentation.
try this:
in First Activity:
Intent first = new Intent(ActivityA,this, ActivityB.class);
startActivityForResult(first, 1);
Now in Second activity: set Result during finish()
Intent intent = new Intent();
intent.putExtra("result",result); //pass intent extra here
setResult(RESULT_OK,intent);
finish();
First activity Catch the result;
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
// check if the request code is same as what is passed here it is 1
if(requestCode==1)
{
String message=data.getStringExtra("result");
//get the result
}
}
If you call finish() to avoid that the user go back to SendMessageActivity.class, you can set this flags to your intent:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
This will open the MainActivity and remove the SendMessageActivity from the activities stack.
I have the following situation:
Activity A starts Activity B, by using startActivityForResult
Activity B then returns an ArrayList of Strings to Activity A by using on finish().
Here is a code example of what exactly Activity B does:
ArrayList<String> urls = new ArrayList<>();
urls.add("Some string");
Intent intent = new Intent();
intent.putStringArrayListExtra(KEY, urls);
setResult(Activity.RESULT_OK, intent);
finish();
Then Activity A receive the data in onActivityResult(...)
The issue I have is that when the user taps the done button and Activity B's code example executes, Activity B freezes for about 3 seconds (when I have about 2 strings in the ArrayList). The more strings I have in the ArrayList the longer it freezes. I have more or less determined that it is finish() that causes the UI thread to freeze.
Is there a way to call finish() without freezing Activity B? If not, why is this happening?
EDIT:
Here is the full example:
/**
* Background task
*/
private class gatherUrlsTask extends AsyncTask<ArrayList<PictureEntry>, Integer, Intent> {
#Override
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
bt_done.setVisibility(View.GONE);
fab_add_picture.setVisibility(View.GONE);
}
#SafeVarargs
#Override
protected final Intent doInBackground(ArrayList<PictureEntry>... params) {
ArrayList<String> imagePaths = new ArrayList<>();
for (PictureEntry pictureEntry : params[0]) {
if (pictureEntry.isSelected()) {
imagePaths.add(pictureEntry.getPath());
}
}
if (imagePaths.size() == 0) {
Toast.makeText(getApplicationContext(), R.string.please_select_atleast_one_image, Toast.LENGTH_LONG).show();
return null;
} else {
Intent intent = new Intent();
intent.putStringArrayListExtra(SELECTED_IMAGES_KEY, imagePaths);
return intent;
}
}
#Override
protected void onPostExecute(Intent intent) {
setResult(Activity.RESULT_OK, intent);
finish();
}
}
However I can remove everything from the AsyncTask since it did not have any effect on performance.
i don't know what is cause of that, but for prevent ui getting freezed, use asyncTask and then in the onPostExcecute call finish()
I have an activity which transfer a string datatype to another activity which then uses that string and calls a method from another class which returns a string. I want to use that method to display the string in the current activity.
So visually it goes (activity 1) -- string--> (activity 2). Activity 2 uses that string to call a method in a different java class which returns a type string which i want to display on the screen along with a few buttons.
So some pseudo code:
say The method in a different java class is:
public static String getStringexample(String n) {
return "hello" + " " + n;
}
and my activity class is:
public class manage extends Activity {
protected void onCreate(bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContainerView(R.layout.activity_manage);
Intent intent = getIntent();
String example = intent.getExtras().getString("intentid");
i'm lost after this..not sure how to use what i got from the intent to display it on the screen in java code.
Information between activities is passed in 'extras'. That is just a collection of string keys and values.
Both sides need to use the same keys, so define static final strings with they keys that your destination activity expects.
Then read the values from the extras using the key and go from there:
public class DestinationActivity extends Activity {
// let your callers know how to pass you the information you need
public static final String EXTRA_N = "n";
private TextView resultText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_destination);
resultText = (TextView) findViewById(R.id.resultText);
// get the information you was passed
Intent intent = getIntent();
String n = intent.getStringExtra(EXTRA_N);
// do your transformation using the other class
String example = DifferentClass.getStringexample(n);
// display the transformed string
resultText.setText(example);
}
// ...
}
The calling activity sends the information like this:
Intent intent = new Intent(this, DestinationActivity.class);
intent.putExtra(DestinationActivity.EXTRA_N, "foo");
startActivity(intent);
Good luck
You can start activity as
Intent i = new Intent(this, SecondActivity.class);
startActivityForResult(i, 1);
Then return to first activity from second activity
Intent returnIntent = new Intent();
returnIntent.putExtra("result",yourdata);
setResult(RESULT_OK,returnIntent);
finish();
In your first activity you will get result by using below code
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == RESULT_OK){
String result=data.getStringExtra("result");
}
if (resultCode == RESULT_CANCELED) {
//Write your code if there's no result
}
}
}