I am trying to expose media items to other media apps that can browse my app's content through my MediaBrowserServiceCompat service.
In my onLoadChildren method I am constructing MediaBrowserCompat.MediaItem with a MediaDescriptionCompat that includes a Bundle that has some extras that I need to play the item.
public class Service extends MediaBrowserServiceCompat {
...
#Override
public void onLoadChildren(#NonNull String parentId, #NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
val bundle = Bundle().apply {
putString("extra", "some value")
}
MediaDescriptionCompat description = new MediaDescriptionCompat.Builder()
.setMediaId(mediaId)
.setExtras(bundle)
.setTitle("title")
.setSubtitle("subtitle")
.setIconUri(uri)
.build();
MediaBrowserCompat.MediaItem item = new MediaBrowserCompat.MediaItem(description, MediaBrowserCompat.MediaItem.FLAG_PLAYABLE);
val items = ArrayList<MediaBrowserCompat.MediaItem>()
items.add(item)
result.sendResult(items)
}
So in the onPlayFromMediaId(String mediaId, Bundle extras) callback that I get when the user has clicked on the item, I am getting the right mediaId but the extras is an empty bundle.
private class MediaSessionCallback extends MediaSessionCompat.Callback {
...
#Override
public void onPlayFromMediaId(String mediaId, Bundle extras) {
super.onPlayFromMediaId(mediaId, extras);
//here extras is empty
}
I am sure that the MediaItem has the extras bundle when sent in the Result<List<MediaBrowserCompat.MediaItem>> result in onLoadChildren but I am not sure why it is being returned empty. What can cause such an issue?
Thank you!
I dont think you are actually getting the bundle. you set the parameter Bundle extra but I dont think there is actually anything in that bundle
usually how I have done it in the past after I create the bundle
to retrieve it would do something like this
create a variable to store the received
val extra:String
then use that string variable to get the bundle you created
extra = bundle.getstring("extra")
which "extra" is matching your key for the bundle that you created up top
which you pretty much have only your not actually getting the string from the bundle that the .getstring("extra") would get
Have same issue and I can't found relation between MediaDescriptionCompat's extras and onPlayFromMediaId's extras. So "mediaId" - that is only information you got from MediaItem and you need put all your data for onPlayFromMediaId here.
Related
I am trying to get data from a parceleable of the next way:
First, create a Bundle of the following way:
final Bundle extras = new Bundle();
I set the data
extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, data);
And in the other activity I try to get the data of the next way:
public Connection onCreateIncomingConnection(PhoneAccountHandle phoneAccountHandle, ConnectionRequest connectionRequest) {
Log.e(TAG, "onCreateIncomingConnection");
final Bundle bundle = connectionRequest.getExtras();
final Data data = (Data) bundle.get(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS);
But when I try to get the Data this is always null, but I check that this is not null when I set the data.
Any idea of why Data become to null?
Thanks
replace .get with .getParcelable
I'm building an app and decided to use Firebase's cloud messaging. The problem I have is that I have no idea how to handle the notification data I get. As far as I know, when you open the notification from background you get intent with the data sent from server in launcher activity. So I have something like this in my launcher activity:
Intent intentOpen;
String message = getIntent().getStringExtra("message");
if(message != null) {
intentOpen = new Intent(this, MainActivity.class);
if (message.equals(this.getResources().getString(R.string.new_shared_file))) {
intentOpen.putExtra(MainActivity.nType, "SHARING");
} else {
intentOpen.putExtra(MainActivity.nType, "SERVICES");
}
}
}
And in my main activity I want to get the nType to determine which fragment should app open:
public static String nType = "notification_type";
if (getIntent().hasExtra(nType)) {
String notification = getIntent().getStringExtra(nType);
if (notification.equals("SHARING")) {
displayView(R.id.nav_shared_files);
} else {
displayView(R.id.nav_account);
}
} else if (savedInstanceState == null) {
displayView(R.id.nav_online_files);
}
So how do I get the String across to the main activity (which I get to after two other activities). Or is there some other way (like from server side) to get the String to the main activity?
Thanks for your answers in advance.
Sure for example you can create enum class with instance:
public enum DataManager {
INSTANCE;
private String data;
public void setData(String data) {
this.data = data;
}
public String getData() {
return data;
}
}
So in first activity when you get data you call:
DataManager.INSTANCE.setData("whateverdata");
And in activity you need data you just call:
String savedData = DataManager.INSTANCE.getData();
In your launcher activity you will get message like this if you send message from console as additional filed option in firebase console:
Regarding image up, you get image as custom data field, otherwise you will not get message in you case. In case if you app is in foreground, you will get your notification data in method onReceiveMessage inside FirebaseNotificationService.
Intent intentOpen;
String image = getIntent().getStringExtra("image"); // or imageUrl
Sending data to other activities must be done over intent arguments, if you want to go this way, you should always put whatever arguments you need to intent when starting next activity. And of course you can choose some other ways to passing data to other activities.
What is faster? Adding a bunch of string values to a bundle and then adding that to an intent? Or just adding the values to an intent using intent.putExtra()? Or doesn't it make much difference?
A Google search gave me tutorials, but not much of an answer. Just asking out of curiosity, wondering if it would affect performance to use one or the other. This got close, but does not answer what I would like to know.
Creating Bundle on your own and then adding that to an intent should be faster.
According to the source code, Intent.putExtra(String, String) method looks like this:
public Intent putExtra(String name, String value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putString(name, value);
return this;
}
So, it will always check at first if Bundle mExtras was already created. That's why it's probably a bit slower with big sequence of String additions. Intent.putExtras(Bundle) looks like this:
public Intent putExtras(Bundle extras) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putAll(extras);
return this;
}
So, it will check if (mExtras == null) only once and later add all the values to the internal Bundle mExtras with Bundle.putAll():
public void putAll(Bundle map) {
unparcel();
map.unparcel();
mMap.putAll(map.mMap);
// fd state is now known if and only if both bundles already knew
mHasFds |= map.mHasFds;
mFdsKnown = mFdsKnown && map.mFdsKnown;
}
Bundle is backed up by a Map (HashMap to be precise), so adding all Strings at once to this map should be also faster than adding Strings one by one.
I have been working on a e-commerce application for a while, and now I have a ListView that displays a list of products - Each products = 1 ImageView and some TextViews-.
I set an onItemClick listener on that ListView, the event that I want to occur when I click on one of that listView products is, Start the i new Activity, 'ProductDetails' that displays more informations on the product I have clicked on.
I have already asked this question somewhere else, but I didn't get a clear answer,
They said that I have to create a new 'list\details' project, but this can't happen now, as I've working on that project for like 20 days, and can't start all over again.
You can't send a TextView or an ImageView from Activity to Activity. what you can send instead is it's contents. so for example if you want to pass the information from the TextView you will need to pass the source String that is displayed there (Or extract the String from the TextView) you do that by passing a Bundle from the calling Activity to the invoked one or simply by putting it as an Extra:
intent.putExtra("string name", value);
and in the following Activity you get this data:
Intent intent = getIntent();
bundle = intent.getExtras();
bundle.getString("string name");
Then in the following Activity create a TextView with the passed String.
Same way is handled with the ImageView by passing the it's path.
Sorry I have posted an answer but was only a link to another site so it was deleted :-(
Here I come again with what could be the solution:
In your first activity, you need to use intent.putExtra(...) and retrieve the datas in your second activity with intent.getExtra(...).
Example activity 1:
i.putExtra("title01", yourDataCollection.get(position).get(KEY_TITLE01));
Activity 2 :
this.title01 = i.getStringExtra("title01");
There is a full project here : http://www.codeproject.com/Articles/507651/Customized-Android-ListView-with-Image-and-Text
Android uses intent to allow Activitys to interact. If you want to show a details of product, probably you have a Class that describe that product and with the information it holds you fill up your ListView. If you let the class Product implements Serializable you can use Intent.putExtra(String name, Serializable obj), to pass the Product description between Activitys. In ProductDetailsActivity you can use:
getIntent(). getSerializableExtra (String name)
to retrive the serializable you put inside the Intent you created to start ProductDetailsActivity
If you pass your model class around many times using Intent, perhaps it could implement the Parcelable interface for convenience. For example:
class ProductData implements Parcelable {
protected String name;
protected String someOtherData;
public static final Parcelable.Creator<ProductData> CREATOR = new Parcelable.Creator<ProductData>() {
#Override
public ProductData createFromParcel(Parcel source) {
return new ProductData(source);
}
#Override
public ProductData[] newArray(int size) {
return new ProductData[size];
}
};
public ProductData(){
}
public ProductData(Parcel source){
readFromParcel(source);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(someOtherData);
}
public void readFromParcel(Parcel source){
name = source.readString();
someOtherData = source.readString();
}
// Here goes the rest of your model code
}
Then you can easily pass the object to another Activity using an Intent:
intent.putExtra("product", productData);
and later get the data using
ProductData productData = intent.getParcelableExtra("product");
This question already has answers here:
What is a "bundle" in an Android application
(12 answers)
Closed 7 years ago.
I am new to android application development, and can't understand what does bundle actually do for us.
Can anyone explain it for me?
I am new to android application development and can't understand what
does bundle actually do for us. Can anyone explain it for me?
In my own words you can image it like a MAP that stores primitive datatypes and objects as couple key-value
Bundle is most often used for passing data through various Activities. Provides putType() and getType() methods for storing and retrieving data from it.
Also Bundle as parameter of onCreate() Activity's life-cycle method can be used when you want to save data when device orientation is changed (in this case activity is destroyed and created again with non null parameter as Bundle).
More about Bundle at its methods you can read reference at developer.android.com where you should start and then make some demo applications to get experience.
Demonstration examples of usage:
Passing primitive datatypes through Activities:
Intent i = new Intent(ActivityContext, TargetActivity.class);
Bundle dataMap = new Bundle();
dataMap.putString("key", "value");
dataMap.putInt("key", 1);
i.putExtras(dataMap);
startActivity(i);
Passing List of values through Activities:
Bundle dataMap = new Bundle();
ArrayList<String> s = new ArrayList<String>();
s.add("Hello");
dataMap.putStringArrayList("key", s); // also Integer and CharSequence
i.putExtras(dataMap);
startActivity(i);
Passing Serialized objects through Activities:
public class Foo implements Serializable {
private static final long serialVersionUID = 1L;
private ArrayList<FooObject> foos;
public Foo(ArrayList<FooObject> foos) {
this.foos = foos;
}
public ArrayList<FooObject> getFoos() {
return this.foos;
}
}
public class FooObject implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
public FooObject(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Then:
Bundle dataMap = new Bundle();
ArrayList<FooObject> foos = new ArrayList<FooObject>();
foos.add(new FooObject(1));
dataMap.putSerializable("key", new Foo(foos));
Pass Parcelable objects through Activities:
There is much more code so here is article how to do it:
Parcel data to pass between Activities using Parcelable classes
How to retrieve data in target Activity:
There is one magic method: getIntent() that returns Intent (if there are any data also with extended data) that started Activity from there method is called.
So:
Bundle dataFromIntent = getIntent().getExtras();
if (dataFromIntent != null) {
String stringValue = dataFromIntent.getString("key");
int intValue = dataFromIntent.getInt("key");
Foo fooObject = (Foo) dataFromIntent.getSerializable("key");
// getSerializble returns Serializable so we need to cast to appropriate object.
ArrayList<String> stringArray = dataFromIntent.getStringArrayList("key");
}
Usage of Bundle as parameter of onCreate() method:
You are storing data in onSaveInstanceState() method as below:
#Override
public void onSaveInstanceState(Bundle map) {
map.putString("key", "value");
map.putInt("key", 1);
}
And restore them in onCreate() method (in this case is Bundle as parameter not null) as below:
#Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
String stringValue = savedInstanceState.getString("key");
int intValue = savedInstanceState.getString("key");
}
...
}
Note: You can restore data also in onRestoreInstanceState() method but it's not common (its called after onStart() method and onCreate() is called before).
In general english: "It is a collection of things, or a quantity of material, tied or wrapped up together."
same way in Android "It is a collection of keys and its values, which are used to store some sort of data in it."
Bundle is generally used for passing data between various component. Bundle class which can be retrieved from the intent via the getExtras() method.
You can also add data directly to the Bundle via the overloaded putExtra() methods of the Intent objects. Extras are key/value pairs, the key is always of type String. As value you can use the primitive data types.
The receiving component can access this information via the getAction() and getData() methods on the Intent object. This Intent object can be retrieved via the getIntent() method. And
the component which receives the intent can use the getIntent().getExtras() method call to get the extra data.
MainActivity
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString(“Key“, myValue);
intent.putExtras(bundle);
startActivity(intent);
SecondActivity
Bundle bundle = getIntent().getExtras();
String myValue= bundle.getString(“key“);
A collection of things, or a quantity of material, tied or wrapped up together. it is the dictionary meaning...By the same Bundle is a collection of data. The data may be of any type i.e String, int,float , boolean and any serializable data. We can share& save the data of one Activity to another using the bundle Bundle.
Consider it as a Bundle of data, used while passing data from one Activity to another.
The documentation defines it as
"A mapping from String values to various Parcelable types."
You can put data inside the Bundle and then pass this Bundle across several activities. This is handy because you don't need to pass individual data. You put all the data in the Bundle and then just pass the Bundle, instead of sending the data individually.
It's literally a bundle of things; information: You put stuff in there (Strings, Integers, etc), and you pass them as a single parameter (the bundle) when use an intent for instance.
Then your target (activity) can get them out again and read the ID, mode, setting etc.
A mapping from String values to various Parcelable types.Click here
Example:
Intent mIntent = new Intent(this, Example.class);
Bundle mBundle = new Bundle();
mBundle.extras.putString(key, value);
mIntent.putExtras(mBundle);
Send value from one activity to another activity.