I'm trying to add a custom user action to my media session so that it shows up on the android auto action card, but I can't seem to get it to work. I've looked around, but didn't find much on how to explicitly add a custom action. I've included all the relevant code that is a part of my implementation of the only custom action I am trying to implement.
I would like to know what is it I'm missing and/or is doing wrong. Thank you.
public class MyMediaBrowserService extends MediaBrowserServiceCompat{
//Variables Declared here ...
#Override
public void onCreate(){
mediaSession = new MediaSessionCompat(this, TAG);
mediaSessionCallback = new MyMediaSessionCallback();
mediaSession.setCallback(mediaSessionCallback);
// Enable callbacks from MediaButtons and TransportControls
mediaSession.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
MediaSessionCompat.Token token = mediaSession.getSessionToken();
setSessionToken(token);
mediaNotificationManager = new MediaNotificationManager(this);
// Set an initial PlaybackState with ACTION_PLAY, so media
buttons can start the player
mStateBuilder = new PlaybackStateCompat.Builder()
.setActions(
PlaybackStateCompat.ACTION_PLAY |
PlaybackStateCompat.ACTION_PAUSE |
PlaybackStateCompat.ACTION_SKIP_TO_NEXT |
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS)
.addCustomAction(CUSTOM_ACTION_REPEAT, "Repeat Mode",
R.drawable.ic_repeat_none);
mediaSession.setPlaybackState(mStateBuilder.build());
mediaSession.setActive(true);
mediaPlayer = new DefaultMediaPlayer(this,
new DefaultMediaPlaybackListener());
}
...
public class MyMediaSessionCallback extends
MediaSessionCompat.Callback {
//Variables Declared here ...
// The following methods are actually implemented in the
// project, and functions as they are supposed to.
// They are mentioned here for the sake of showing their
// existence with relations to the PlaybackStateCompat set
// above.
#Override public void onAddQueueItem(MediaDescriptionCompat
description) { ... }
#Override public void onRemoveQueueItem(MediaDescriptionCompat
description) { ... }
#Override public void onPlayFromMediaId(String mediaId,
Bundle extras) { .... }
#Override public void onPlay() { ... }
#Override public void onPause() { ... }
#Override public void onStop() { ... }
#Override public void onSkipToNext() { ... }
#Override public void onSkipToPrevious() { ... }
#Override public void onSeekTo(long pos) { ... }
// This is the actual implement of the onCustomAction method
// I never got it working so I figured I'll start by logging it
// first before spending time coding it
#Override
public void onCustomAction(String action,
Bundle extras) {
if(action.equals(CUSTOM_ACTION_REPEAT))
Log.e(TAG, "Custom action is REPEAT");
}
...
}
}
In order to add a custom action and given a PlayBackStateCompat.Builder you can add a custom action as follows:
mStateBuilder.addCustomAction(
new PlaybackStateCompat.CustomAction.Builder(
CUSTOM_ACTION_REPLAY,
getString(R.string.custom_action_replay),
R.drawable.ic_replay).build()
);
Then you must add the code to handle the custom action as you already did.
The code above should work, and correctly display the actions on Android Auto, i use this to display the custom action. Hope this helps even if i am little late
Related
I am using yFiles library and I am handling a Graph2DView object named view. To activate mouseWheel scroll for this object, I have to add a listener in registerViewListeners function. However, I also want to be notified also in myClass mouseWheelMoved function when mouseweel
public class MyClass extends MyBaseClass implements MouseWheelListener {
Graph2DView view;
// .....
#Override
protected void registerViewListeners()
{
Graph2DViewMouseWheelScrollListener wheelListener = new Graph2DViewMouseWheelScrollListener();
wheelListener.addToCanvas(view);
// The two precedent instruction is equivalent to
// view.getCanvasComponent().addMouseWheelListener(this);
}
#Override
public void mouseWheelMoved(MouseWheelEvent e)
{
// some work ...
}
}
Problem:
If i register my view object through registerViewListeners
#Override
protected void registerViewListeners()
{
Graph2DViewMouseWheelScrollListener wheelListener = new Graph2DViewMouseWheelScrollListener();
wheelListener.addToCanvas(view);
}
My mouseWheelMoved function is no longer notified:
#Override
public void mouseWheelMoved(MouseWheelEvent e)
{
// not called
}
Your description sounds as if you have simply removed the registration for your event listener.
In the place where you instantiate MyClass, please also add:
view.getCanvasComponent().addMouseWheelListener(myClassInstance); // register listener
If you don't register your listener, it will not be called, of course. Only instantiating it will not suffice.
I'm implementing an MVP architecture with Retrofit, and RxJava2 (with RxAndroid). I have the following setup
NetworkInterface.java where retrofit calls lie
public interface NetworkInterface {
#GET("/input")
Single<List<InformationData>> getInfoData();
}
InformationDataDao.java Data access layer for the information data
#Dao
public interface InformationDataDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
Completable createInfoData(List<InformationData> infoData);
}
MainPresenter.java where the calls are being made public class MainPresenter {
public MainPresenter() {
}
// Method called to initialize the subscription
#Override
public void subscribe() {
this.collectInfoData();
}
private void collectInfoData() {
Single<List<InformationData>> singleInfoData = networkInterface.getInfoData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
singleInfoData.subscribe(informationDatas -> {
InformationDataDao informationDataDao = database.informationDataDao();
informationDataDao.createInfoData(informationDatas);
// What made me detect that this was being called twice
Log.d(Constant.LOG_TAG, "Info Data: " + informationDatas.size());
// Rest of the code here
}, Throwable::printStackTrace);
}
}
SplashActivity.java The method that calls the presenter
public class SplashActivity extends AppCompatActivity {
// Helps in getting the location
private FusedLocationProviderClient locationClient;
private SplashPresenter mPresenter;
#Override
protected void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.activity_splash);
mPresenter = new SplashPresenter();
}
#Override
protected void onResume() {
super.onResume();
// These three lines ensure that you have the appropriate permissions to proceed. In the third line for instance, the user will be navigated out to the settings pane to turn on location.
// When he/she returns to the activity, the onResume is called so I'm assuming that's the best place to start the presenter
this.ensureHasPermissions();
boolean isGoogleServiceAvailable = this.ensureGoogleServiceAvailability();
boolean isLocationServiceAvailable = this.ensureLocationServiceAvailable();
if (isLocationServiceAvailable && isGoogleServiceAvailable) {
locationClient.getLastLocation()
.addOnSuccessListener(this, location -> {
// Set the closest location and subscribe
presenter.setClosestLocation(location);
presenter.subscribe();
})
.addOnFailureListener(this, Throwable::printStackTrace);
}
}
}
From the SplashPresenter.java, the log is printed twice, indicating that the complete callback was called twice. Is there any idea why this may be so? I'm quite new to RxJava2 and will greatly appreciate the feedback.
Thanks.
I've created an Asynctask in an activity and now i want to return the variable "realimage" to that Asynctask but i cant seem to access it...
public class PhotoUtils
{
public static Photo getImage(String id)
{
unsplash.getPhoto(id, new Unsplash.OnPhotoLoadedListener()
{
#Override
public void onComplete(Photo photo)
{
Photo realImage=photo;
}
#Override
public void onError(String error)
{
}
});
return realImage; //This line shows error that cannot resolve symbol
realImage
}
}
This is my Async Task which is in the other activity
public class ImageTask extends AsyncTask<Photo,Void,Photo>
{
#Override
protected Photo doInBackground(Photo... photos)
{
Intent intent=getIntent();
Bundle bd=intent.getExtras();
String getId = (String) bd.get("id");
Photo finalPhoto=PhotoUtils.getImage(getId);
return finalPhoto;
}
#Override
protected void onPostExecute(Photo finalPhoto) {
tv1.setText(finalPhoto.getId());
super.onPostExecute(finalPhoto);
}
}
First, looks like you don't even need an Asynctask. Look at the example code
Secondly, you can't return it like that.
OnPhotoLoadedListener is an asynchronous callback.
Just use the image as normal within onComplete.
If you needed to pass back the image to the calling method, extract the callback to a parameter.
// this is void now
public static void getImage(String id, Unsplash.OnPhotoLoadedListener listener) {
unsplash.getPhoto(id, listener);
});
Call this as
PhotoUtils.getImage(id, new Unsplash.OnPhotoLoadedListener() {
// Use image in here
});
Which, if you look closely, all you did was replace normal usage of unsplash.getPhoto with PhotoUtils.getImage, which may be want you want, but you could accomplish a similar approach with a singleton pattern around the unsplash instance variable. That way, you're not rewriting all of Unsplash API calls
I am trying to understand how interfaces work. I have read basic interface tutorials online and watched a few videos so i do have a good idea of what a interface is and its advantages.
Interface
public interface UpyunFormApi {
#Description("上传文件")
#POST("/{bucket}")
#Multipart
public Request upload(#Path("bucket") String bucket, #Part("policy") PolicyPart policy,
#Part("signature") SignaturePart signature, #Part("file") File file, OnRequestListener requestListener,
OnResponseListener<UpyunFormEntity> responseListener, OnErrorListener errorListener);
Code
private UpyunFormApi formApi;
private void uploadAndPushTopic() {
String bucket = UrlManager.getInstance().getUpyunImageBucket();
String secret = UrlManager.getInstance().getUpyunImageSecret();
for (File file : filearr) {
PolicyPart policy = new PolicyPart(bucket);
SignaturePart signature = new SignaturePart(policy, secret);
formApi.upload(bucket, policy, signature, file, uploadRequestListener, uploadResponseListener,
uploadErrorListener);
}
}
private OnRequestListener uploadRequestListener = new OnRequestListener() {
#Override
public void onRequest(Request arg0) {
}
};
private OnErrorListener uploadErrorListener = new OnErrorListener() {
#Override
public void onError(LegolasException arg0) {
}
};
private OnResponseListener<UpyunFormEntity> uploadResponseListener = new OnResponseListener<UpyunFormEntity>() {
#Override
public void onResponse(UpyunFormEntity arg0) {
}
}
};
Why the Responselister works after "formApi.upload()" finished?And I can't find function definition.Help!
I don't understand the code
#Description("上传文件")
#POST("/{bucket}")
#Multipart
Make an interface like :
public interface ChangeItemInterface {
public void doChange(String anyValue);
}
In Adapter,
Intialize interface object like :
ChangeItemInterface changeItemInterface;
In Adapter Constructor,
this.changeItemInterface = context;
In Adapter, From any View Click :
AnyView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
this.changeItemInterface.doChange("AnyValue");
// It will go to the Your Activity Overided method which is explained below this
}
});
In Your Activity implement this interface like :
public class YourActivity extends Activity implements ChangeItemInterface{
/// You'll get override method of your interface, here your call back will come when from adapter click happen
#Override
public void doChange(String anyValue) {
/// Here you can update any value in your activity !
}
}
Hope this demo help you to understand interface use !
Hello i have got function like that:
#Override
public boolean checkExist(String name) {
final boolean check[] = new boolean[] { false };
getAllRecordFromServer(new SearchCallback() {
#Override
public void onSearchResult(Map<String, Item> itemsMap) {
//do some action set true when map key equals name
check[0] = true;
}
#Override
public void onSearchError(XMLPacket error) {
// TODO Auto-generated method stub
}
});
return check[0];
}
I`am looking for solution and found some article but i do not know how to do it in gwt :/
This code do not working properly ... as you know this is asynchronous callback.
How can i fix this problem i must return value after callback ends.
It is not possible to return a value from async call in a method as you have done. That is the basic nature of "Asynchronous" call. You never know when it will return ( network/server delay) and hence your code execution does not wait!!!!!
Do not return a boolean from your method. Instead make your method take a callback.
interface MyCallback {
execute(boolean successfl);
}
public void checkExist(String name, MyCallback callback) {
getAllRecordFromServer(new SearchCallback() {
#Override
public void onSearchResult(Map<String, Item> itemsMap) {
//do some action set true when map key equals name
callback.execute(true);
}
#Override
public void onSearchError(XMLPacket error) {
}
});
}
Maybe a cleaner solution might be to use events and an eventbus (which could be private to your class or maybe shared by everyone so that other components can react to that) when you get your result or not. Then listen for these events and treat them accordingly.
getAllRecordFromServer(new SearchCallback() {
#Override
public void onSearchResult() {
eventBus.fireEvent(new FoundEvent());
}
#Override
public void onSearchError() {
eventBus.fireEvent(new NotFoundEvent());
}
});
This code is not working properly ...
The reason is that Your code is in synchronous model and you are making Asynchronous calls.
I am assuming that you are doing something after you got some result in onSearchResult.
So,stop executing your code until you got the response from server, Why because you dont know that the callmay fail sometime.
If you really want to use the value globally ,then
public boolean returnVal=false;
public void checkExist(String name, MyCallback callback) {
getAllRecordFromServer(new SearchCallback() {
#Override
public void onSearchResult(Map<String, Item> itemsMap) {
returnVal=true;
proceedFurther(itemsMap) //your next lines of code in this method.
}
#Override
public void onSearchError(XMLPacket error) {
stopProceedFurther(); //show some error message to user.
}
});