forked from organicmaps/organicmaps
[android] Supported sound notification about speed cameras
This commit is contained in:
parent
18746aebad
commit
14f31e163b
6 changed files with 200 additions and 2 deletions
BIN
android/res/raw/speed_cams_beep.m4a
Normal file
BIN
android/res/raw/speed_cams_beep.m4a
Normal file
Binary file not shown.
|
@ -1381,6 +1381,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
mAdsRemovalPurchaseController.destroy();
|
||||
if (mBookmarkPurchaseController != null)
|
||||
mBookmarkPurchaseController.destroy();
|
||||
if (mNavigationController != null)
|
||||
mNavigationController.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2294,7 +2296,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
if (mNavigationController != null)
|
||||
mNavigationController.update(Framework.nativeGetRouteFollowingInfo());
|
||||
|
||||
TtsPlayer.INSTANCE.playTurnNotifications();
|
||||
TtsPlayer.INSTANCE.playTurnNotifications(getApplicationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.mapswithme.maps.location.LocationHelper;
|
|||
import com.mapswithme.maps.location.TrackRecorder;
|
||||
import com.mapswithme.maps.maplayer.subway.SubwayManager;
|
||||
import com.mapswithme.maps.maplayer.traffic.TrafficManager;
|
||||
import com.mapswithme.maps.base.MediaPlayerWrapper;
|
||||
import com.mapswithme.maps.routing.RoutingController;
|
||||
import com.mapswithme.maps.scheduling.ConnectivityJobScheduler;
|
||||
import com.mapswithme.maps.scheduling.ConnectivityListener;
|
||||
|
@ -74,6 +75,9 @@ public class MwmApplication extends Application
|
|||
@SuppressWarnings("NullableProblems")
|
||||
@NonNull
|
||||
private PurchaseValidationObservable mPurchaseValidationObservable;
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@NonNull
|
||||
private MediaPlayerWrapper mPlayer;
|
||||
|
||||
@NonNull
|
||||
public SubwayManager getSubwayManager()
|
||||
|
@ -160,6 +164,7 @@ public class MwmApplication extends Application
|
|||
mConnectivityListener.listen();
|
||||
|
||||
mPurchaseValidationObservable = new PurchaseValidationObservable();
|
||||
mPlayer = new MediaPlayerWrapper(this);
|
||||
}
|
||||
|
||||
private void initNotificationChannels()
|
||||
|
@ -336,6 +341,12 @@ public class MwmApplication extends Application
|
|||
return mConnectivityListener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MediaPlayerWrapper getMediaPlayer()
|
||||
{
|
||||
return mPlayer;
|
||||
}
|
||||
|
||||
private native void nativeInitPlatform(String apkPath, String storagePath, String privatePath,
|
||||
String tmpPath, String obbGooglePath, String flavorName,
|
||||
String buildType, boolean isTablet);
|
||||
|
|
172
android/src/com/mapswithme/maps/base/MediaPlayerWrapper.java
Normal file
172
android/src/com/mapswithme/maps/base/MediaPlayerWrapper.java
Normal file
|
@ -0,0 +1,172 @@
|
|||
package com.mapswithme.maps.base;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.RawRes;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.R;
|
||||
|
||||
public class MediaPlayerWrapper
|
||||
{
|
||||
private static final int UNDEFINED_SOUND_STREAM = -1;
|
||||
|
||||
@NonNull
|
||||
private final Application mApp;
|
||||
@Nullable
|
||||
private MediaPlayer mPlayer;
|
||||
@Nullable
|
||||
private MediaPlayer.OnCompletionListener mCompletionListener;
|
||||
private int mStreamResId = UNDEFINED_SOUND_STREAM;
|
||||
|
||||
public MediaPlayerWrapper(@NonNull Application application)
|
||||
{
|
||||
mApp = application;
|
||||
}
|
||||
|
||||
private boolean isCurrentSoundStream(@RawRes int streamResId)
|
||||
{
|
||||
return mStreamResId == streamResId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Application getApp()
|
||||
{
|
||||
return mApp;
|
||||
}
|
||||
|
||||
private void onInitializationCompleted(@NonNull InitializationResult initializationResult)
|
||||
{
|
||||
releaseInternal();
|
||||
mStreamResId = initializationResult.getStreamResId();
|
||||
mPlayer = initializationResult.getPlayer();
|
||||
if (mPlayer == null)
|
||||
return;
|
||||
|
||||
mPlayer.setOnCompletionListener(mCompletionListener);
|
||||
mPlayer.start();
|
||||
}
|
||||
|
||||
private void releaseInternal()
|
||||
{
|
||||
if (mPlayer == null)
|
||||
return;
|
||||
|
||||
stop();
|
||||
mPlayer.release();
|
||||
mPlayer = null;
|
||||
mStreamResId = UNDEFINED_SOUND_STREAM;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static AsyncTask<Integer, Void, InitializationResult> makeInitTask(@NonNull MediaPlayerWrapper wrapper)
|
||||
{
|
||||
return new InitPlayerTask(wrapper);
|
||||
}
|
||||
|
||||
public void release()
|
||||
{
|
||||
releaseInternal();
|
||||
mCompletionListener = null;
|
||||
}
|
||||
|
||||
public void playback(@RawRes int streamResId,
|
||||
@Nullable MediaPlayer.OnCompletionListener completionListener)
|
||||
{
|
||||
if (isCurrentSoundStream(streamResId) && mPlayer == null)
|
||||
return;
|
||||
|
||||
if (isCurrentSoundStream(streamResId) && mPlayer != null)
|
||||
{
|
||||
mPlayer.start();
|
||||
return;
|
||||
}
|
||||
|
||||
mCompletionListener = completionListener;
|
||||
mStreamResId = streamResId;
|
||||
AsyncTask<Integer, Void, InitializationResult> task = makeInitTask(this);
|
||||
task.execute(streamResId);
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
if (mPlayer == null)
|
||||
return;
|
||||
|
||||
mPlayer.stop();
|
||||
}
|
||||
|
||||
public boolean isPlaying()
|
||||
{
|
||||
return mPlayer != null && mPlayer.isPlaying();
|
||||
}
|
||||
|
||||
public void playbackSpeedCamsWarningSignal(@Nullable MediaPlayer.OnCompletionListener completionListener)
|
||||
{
|
||||
playback(R.raw.speed_cams_beep, completionListener);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static MediaPlayerWrapper from(@NonNull Context context)
|
||||
{
|
||||
MwmApplication app = (MwmApplication) context.getApplicationContext();
|
||||
return app.getMediaPlayer();
|
||||
}
|
||||
|
||||
private static class InitPlayerTask extends AsyncTask<Integer, Void, InitializationResult>
|
||||
{
|
||||
@NonNull
|
||||
private final MediaPlayerWrapper mWrapper;
|
||||
|
||||
public InitPlayerTask(@NonNull MediaPlayerWrapper wrapper)
|
||||
{
|
||||
mWrapper = wrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InitializationResult doInBackground(Integer... params)
|
||||
{
|
||||
int resId = params[0];
|
||||
MediaPlayer player = MediaPlayer.create(mWrapper.getApp(), resId);
|
||||
return new InitializationResult(player, resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(InitializationResult initializationResult)
|
||||
{
|
||||
super.onPostExecute(initializationResult);
|
||||
mWrapper.onInitializationCompleted(initializationResult);
|
||||
}
|
||||
}
|
||||
|
||||
private static class InitializationResult
|
||||
{
|
||||
@Nullable
|
||||
private final MediaPlayer mPlayer;
|
||||
@RawRes
|
||||
private final int mStreamResId;
|
||||
|
||||
private InitializationResult(@Nullable MediaPlayer player, @RawRes int streamResId)
|
||||
{
|
||||
mPlayer = player;
|
||||
mStreamResId = streamResId;
|
||||
}
|
||||
|
||||
@RawRes
|
||||
private int getStreamResId()
|
||||
{
|
||||
return mStreamResId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private MediaPlayer getPlayer()
|
||||
{
|
||||
return mPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@ import android.widget.TextView;
|
|||
import com.mapswithme.maps.Framework;
|
||||
import com.mapswithme.maps.MwmActivity;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.base.MediaPlayerWrapper;
|
||||
import com.mapswithme.maps.bookmarks.BookmarkCategoriesActivity;
|
||||
import com.mapswithme.maps.bookmarks.data.DistanceAndAzimut;
|
||||
import com.mapswithme.maps.location.LocationHelper;
|
||||
|
@ -443,4 +444,9 @@ public class NavigationController implements TrafficManager.TrafficCallback, Vie
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
MediaPlayerWrapper.from(mBottomFrame.getContext()).release();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Locale;
|
|||
import com.mapswithme.maps.Framework;
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.base.MediaPlayerWrapper;
|
||||
import com.mapswithme.util.Config;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
|
@ -161,6 +162,10 @@ public enum TtsPlayer
|
|||
});
|
||||
}
|
||||
|
||||
public boolean isSpeaking() {
|
||||
return mTts != null && mTts.isSpeaking();
|
||||
}
|
||||
|
||||
private static boolean isReady()
|
||||
{
|
||||
return (INSTANCE.mTts != null && !INSTANCE.mUnavailable && !INSTANCE.mInitializing);
|
||||
|
@ -181,8 +186,10 @@ public enum TtsPlayer
|
|||
}
|
||||
}
|
||||
|
||||
public void playTurnNotifications()
|
||||
public void playTurnNotifications(@NonNull Context context)
|
||||
{
|
||||
if (MediaPlayerWrapper.from(context).isPlaying())
|
||||
return;
|
||||
// It's necessary to call Framework.nativeGenerateTurnNotifications() even if TtsPlayer is invalid.
|
||||
final String[] turnNotifications = Framework.nativeGenerateNotifications();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue