Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2015-12-29 09:57:38 +01:00
commit 8d8cbd5527
6 changed files with 263 additions and 98 deletions

View file

@ -9,6 +9,7 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
-->
<string name="shared_string_not_selected">Not selected</string>
<string name="rec_split">Recorder Split</string>
<string name="rec_split_title">Use Recorder Split</string>
<string name="rec_split_desc">Rewrite clips when used space exceeds the storage size</string>

View file

@ -50,7 +50,7 @@ public class AudioVideoNoteMenuController extends MenuController {
@Override
public void onClick(DialogInterface dialog, int which) {
if (plugin != null) {
plugin.deleteRecording(getRecording());
plugin.deleteRecording(getRecording(), true);
getMapActivity().getContextMenu().close();
}
}

View file

@ -2,6 +2,7 @@ package net.osmand.plus.audionotes;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
@ -118,6 +119,7 @@ public class AudioVideoNoteRecordingMenu {
}
public void hide() {
stopCounter();
view.setVisibility(View.GONE);
plugin.stopCamera();
viewfinder.removeAllViews();
@ -169,16 +171,34 @@ public class AudioVideoNoteRecordingMenu {
centerButtonView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
rec(plugin.getMapActivity());
rec(plugin.getMapActivity(), false);
}
});
applyViewfinderVisibility();
}
public boolean restartRecordingIfNeeded() {
boolean restart = false;
CurrentRecording recording = plugin.getCurrentRecording();
if (recording != null
&& recording.getType() == AVActionType.REC_VIDEO
&& plugin.AV_RECORDER_SPLIT.get()) {
int clipLength = plugin.AV_RS_CLIP_LENGTH.get() * 60;
int duration = (int) ((System.currentTimeMillis() - startTime) / 1000);
restart = duration >= clipLength;
if (restart) {
rec(getMapActivity(), true);
}
}
return restart;
}
public void updateDuration() {
TextView timeText = (TextView) view.findViewById(R.id.timeText);
int duration = (int) ((System.currentTimeMillis() - startTime) / 1000);
timeText.setText(Algorithms.formatDuration(duration));
if (plugin.getCurrentRecording() != null) {
TextView timeText = (TextView) view.findViewById(R.id.timeText);
int duration = (int) ((System.currentTimeMillis() - startTime) / 1000);
timeText.setText(Algorithms.formatDuration(duration));
}
}
protected void applyViewfinderVisibility() {
@ -236,21 +256,30 @@ public class AudioVideoNoteRecordingMenu {
return res;
}
public void rec(final MapActivity mapActivity) {
public void rec(final MapActivity mapActivity, final boolean restart) {
stopCounter();
final CurrentRecording recording = plugin.getCurrentRecording();
int delay;
if (recording != null && recording.getType() == AVActionType.REC_PHOTO) {
delay = 200;
} else {
delay = 1;
}
handler.postDelayed(new Runnable() {
@Override
public void run() {
CurrentRecording recording = plugin.getCurrentRecording();
if (recording != null) {
if (recording.getType() == AVActionType.REC_PHOTO) {
plugin.shoot();
} else {
plugin.stopRecording(mapActivity);
plugin.stopRecording(mapActivity, restart);
if (restart) {
startCounter();
}
}
}
}
}, 200);
}, delay);
}
public void recExternal(final MapActivity mapActivity) {
@ -270,7 +299,7 @@ public class AudioVideoNoteRecordingMenu {
private void startCounter() {
startTime = System.currentTimeMillis();
Log.e("111", "START");
if (recTimer != null) {
recTimer.cancel();
}
@ -282,7 +311,9 @@ public class AudioVideoNoteRecordingMenu {
handler.post(new Runnable() {
@Override
public void run() {
updateDuration();
if (!restartRecordingIfNeeded()) {
updateDuration();
}
}
});
}
@ -291,6 +322,7 @@ public class AudioVideoNoteRecordingMenu {
}
private void stopCounter() {
Log.e("111", "STOP");
if (recTimer != null) {
recTimer.cancel();
recTimer = null;

View file

@ -21,6 +21,7 @@ import android.media.MediaRecorder;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Build;
import android.os.StatFs;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.view.Display;
@ -72,10 +73,12 @@ import org.apache.commons.logging.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
@ -782,7 +785,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
@Override
public void mapActivityScreenOff(MapActivity activity) {
stopCameraRecording(activity);
stopRecording(activity, false);
}
@Override
@ -803,7 +806,13 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
finishPhotoRecording(false);
} else {
activity.getContextMenu().close();
stopRecording(activity);
if (currentRecording.getType() == AVActionType.REC_VIDEO && AV_RECORDER_SPLIT.get()) {
runAction = AV_DEFAULT_ACTION_VIDEO;
LatLon latLon = getNextRecordingLocation();
actionLat = latLon.getLatitude();
actionLon = latLon.getLongitude();
}
stopRecording(activity, false);
}
finishRecording();
}
@ -854,21 +863,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
public void recordVideoCamera(final double lat, final double lon, final MapActivity mapActivity) {
final CamcorderProfile p = CamcorderProfile.get(AV_VIDEO_QUALITY.get());
final Camera.Size mPreviewSize;
if (mSupportedPreviewSizes != null) {
int width;
int height;
if (recordingMenu.isLandscapeLayout()) {
width = p.videoFrameWidth;
height = p.videoFrameHeight;
} else {
height = p.videoFrameWidth;
width = p.videoFrameHeight;
}
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
} else {
mPreviewSize = null;
}
final Camera.Size mPreviewSize = getPreviewSize();
final SurfaceView view;
if (mPreviewSize != null) {
@ -888,23 +883,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
MediaRecorder mr = new MediaRecorder();
try {
Parameters parameters = cam.getParameters();
// camera focus type
List<String> sfm = parameters.getSupportedFocusModes();
if (sfm.contains("continuous-video")) {
parameters.setFocusMode("continuous-video");
}
int cameraOrientation = getCamOrientation(mapActivity, Camera.CameraInfo.CAMERA_FACING_BACK);
cam.setDisplayOrientation(cameraOrientation);
parameters.set("rotation", cameraOrientation);
if (mPreviewSize != null) {
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
}
cam.setParameters(parameters);
cam.setPreviewDisplay(holder);
cam.startPreview();
startCamera(mPreviewSize, holder);
cam.unlock();
mr.setCamera(cam);
@ -917,27 +896,12 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
return;
}
String ext = MPEG4_EXTENSION;
// if (AV_VIDEO_FORMAT.get() == VIDEO_OUTPUT_3GP) {
// ext = THREEGP_EXTENSION;
// }
final File f = getBaseFileName(lat, lon, app, ext);
mr.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mr.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// if (AV_VIDEO_FORMAT.get() == VIDEO_OUTPUT_3GP) {
// mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// } else {
// mr.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// }
giveMediaRecorderHintRotatedScreen(mapActivity, mr);
//mr.setPreviewDisplay(holder.getSurface());
mr.setProfile(p);
mr.setOutputFile(f.getAbsolutePath());
final File f = getBaseFileName(lat, lon, app, MPEG4_EXTENSION);
initMediaRecorder(mr, p, f);
try {
if (AV_RECORDER_SPLIT.get()) {
cleanupSpace();
}
runMediaRecorder(mapActivity, mr, f);
} catch (Exception e) {
logErr(e);
@ -951,6 +915,17 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
recordingMenu.show();
}
private void initMediaRecorder(MediaRecorder mr, CamcorderProfile p, File f) {
mr.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mr.setVideoSource(MediaRecorder.VideoSource.CAMERA);
giveMediaRecorderHintRotatedScreen(mapActivity, mr);
//mr.setPreviewDisplay(holder.getSurface());
mr.setProfile(p);
mr.setOutputFile(f.getAbsolutePath());
}
private void giveMediaRecorderHintRotatedScreen(final MapActivity mapActivity, final MediaRecorder mr) {
if (Build.VERSION.SDK_INT >= 9) {
try {
@ -1013,6 +988,48 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
mapActivity.setRequestedOrientation(requestedOrientation);
}
private Camera.Size getPreviewSize() {
final CamcorderProfile p = CamcorderProfile.get(AV_VIDEO_QUALITY.get());
final Camera.Size mPreviewSize;
if (mSupportedPreviewSizes != null) {
int width;
int height;
if (recordingMenu.isLandscapeLayout()) {
width = p.videoFrameWidth;
height = p.videoFrameHeight;
} else {
height = p.videoFrameWidth;
width = p.videoFrameHeight;
}
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
} else {
mPreviewSize = null;
}
return mPreviewSize;
}
protected void startCamera(Camera.Size mPreviewSize, SurfaceHolder holder) throws IOException {
Parameters parameters = cam.getParameters();
// camera focus type
List<String> sfm = parameters.getSupportedFocusModes();
if (sfm.contains("continuous-video")) {
parameters.setFocusMode("continuous-video");
}
int cameraOrientation = getCamOrientation(mapActivity, Camera.CameraInfo.CAMERA_FACING_BACK);
cam.setDisplayOrientation(cameraOrientation);
parameters.set("rotation", cameraOrientation);
if (mPreviewSize != null) {
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
}
cam.setParameters(parameters);
if (holder != null) {
cam.setPreviewDisplay(holder);
}
cam.startPreview();
}
protected void stopCamera() {
try {
if (cam != null) {
@ -1027,18 +1044,44 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
}
private void stopCameraRecording(final MapActivity mapActivity) {
private boolean stopCameraRecording(boolean restart) {
boolean res = true;
if (mediaRec != null) {
mediaRec.stop();
AVActionType type = currentRecording.type;
indexFile(true, mediaRecFile);
mediaRec.release();
mediaRec = null;
indexFile(true, mediaRecFile);
mediaRecFile = null;
stopCamera();
}
if (recordControl != null) {
setRecordListener(recordControl, mapActivity);
if (restart) {
try {
cam.lock();
if (AV_RECORDER_SPLIT.get()) {
cleanupSpace();
}
currentRecording = new CurrentRecording(type);
MediaRecorder mr = new MediaRecorder();
LatLon latLon = getNextRecordingLocation();
final File f = getBaseFileName(latLon.getLatitude(), latLon.getLongitude(), app, MPEG4_EXTENSION);
cam.unlock();
mr.setCamera(cam);
initMediaRecorder(mr, CamcorderProfile.get(AV_VIDEO_QUALITY.get()), f);
mr.prepare();
mr.start();
mediaRec = mr;
mediaRecFile = f;
} catch (Exception e) {
AccessibleToast.makeText(app, e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
res = false;
}
}
}
return res;
}
public void recordAudio(double lat, double lon, final MapActivity mapActivity) {
@ -1162,6 +1205,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
parameters.setGpsLatitude(lat);
parameters.setGpsLongitude(lon);
parameters.setGpsProcessingMethod(locProvider.toUpperCase());
parameters.setGpsTimestamp(System.currentTimeMillis() / 1000);
}
switch (AV_CAMERA_FOCUS_TYPE.get()) {
case AV_CAMERA_FOCUS_HIPERFOCAL:
@ -1353,6 +1397,69 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
}
private void cleanupSpace() {
File[] files = app.getAppPath(IndexConstants.AV_INDEX_DIR).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
return filename.endsWith("." + MPEG4_EXTENSION);
}
});
if (files != null) {
double usedSpace = 0;
for (File f : files) {
usedSpace += f.length();
}
usedSpace /= (1 << 30); // gigabytes
final CamcorderProfile p = CamcorderProfile.get(AV_VIDEO_QUALITY.get());
double bitrate = (((p.videoBitRate + p.audioBitRate) / 8f) * 60f) / (1 << 30); // gigabytes per minute
double clipSpace = bitrate * AV_RS_CLIP_LENGTH.get();
double storageSize = AV_RS_STORAGE_SIZE.get();
double availableSpace = storageSize;
File dir = app.getAppPath("").getParentFile();
if (dir.canRead()) {
StatFs fs = new StatFs(dir.getAbsolutePath());
availableSpace = (double) (fs.getAvailableBlocks()) * fs.getBlockSize() / (1 << 30) - clipSpace;
}
if (usedSpace + clipSpace > storageSize || clipSpace > availableSpace) {
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(File lhs, File rhs) {
return lhs.lastModified() < rhs.lastModified() ? -1 : (lhs.lastModified() == rhs.lastModified() ? 0 : 1);
}
});
boolean wasAnyDeleted = false;
ArrayList<File> arr = new ArrayList<>(Arrays.asList(files));
while (arr.size() > 0
&& (usedSpace + clipSpace > storageSize || clipSpace > availableSpace)) {
File f = arr.remove(0);
double length = ((double) f.length()) / (1 << 30);
Recording r = recordingByFileName.get(f.getName());
if (r != null) {
deleteRecording(r, false);
wasAnyDeleted = true;
usedSpace -= length;
availableSpace += length;
} else if (f.delete()) {
usedSpace -= length;
availableSpace += length;
}
}
if (wasAnyDeleted) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
mapActivity.refreshMap();
}
}, 20);
}
}
}
}
private void runMediaRecorder(final MapActivity mapActivity, MediaRecorder mr, final File f) throws IOException {
mr.prepare();
mr.start();
@ -1375,26 +1482,42 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
recordControl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopRecording(mapActivity);
stopRecording(mapActivity, false);
}
});
}
public void stopRecording(final MapActivity mapActivity) {
public void stopRecording(final MapActivity mapActivity, boolean restart) {
if (!recordingDone) {
recordingDone = true;
if (!recordControl.isVisible()) {
recordControl.setExplicitlyVisible(false);
mapActivity.getMapLayers().getMapInfoLayer().recreateControls();
if (!restart || !stopCameraRecording(true)) {
recordingDone = true;
if (!recordControl.isVisible()) {
recordControl.setExplicitlyVisible(false);
mapActivity.getMapLayers().getMapInfoLayer().recreateControls();
}
stopCameraRecording(false);
if (recordControl != null) {
setRecordListener(recordControl, mapActivity);
}
SHOW_RECORDINGS.set(true);
mapActivity.getMapView().refreshMap();
updateWidgetIcon(recordControl);
closeRecordingMenu();
}
stopCameraRecording(mapActivity);
SHOW_RECORDINGS.set(true);
mapActivity.getMapView().refreshMap();
updateWidgetIcon(recordControl);
closeRecordingMenu();
}
}
private LatLon getNextRecordingLocation() {
double lat = mapActivity.getMapLocation().getLatitude();
double lon = mapActivity.getMapLocation().getLongitude();
Location loc = app.getLocationProvider().getLastKnownLocation();
if (loc != null) {
lat = loc.getLatitude();
lon = loc.getLongitude();
}
return new LatLon(lat, lon);
}
private void updateContextMenu(Recording rec) {
if (mapActivity != null && rec != null) {
MapContextMenu menu = mapActivity.getContextMenu();
@ -1450,14 +1573,17 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
recordingByFileName = newMap;
if (isRecording()) {
AVActionType type = currentRecording.type;
finishRecording();
final Recording recordingForMenu = r;
app.runInUIThread(new Runnable() {
@Override
public void run() {
updateContextMenu(recordingForMenu);
}
}, 200);
if (!AV_RECORDER_SPLIT.get() || type != AVActionType.REC_VIDEO) {
final Recording recordingForMenu = r;
app.runInUIThread(new Runnable() {
@Override
public void run() {
updateContextMenu(recordingForMenu);
}
}, 200);
}
}
return true;
@ -1527,14 +1653,16 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
}
public void deleteRecording(Recording r) {
public void deleteRecording(Recording r, boolean updateUI) {
recordings.unregisterObject(r.lat, r.lon, r);
Map<String, Recording> newMap = new LinkedHashMap<>(recordingByFileName);
newMap.remove(r.file.getName());
recordingByFileName = newMap;
Algorithms.removeAllFiles(r.file);
if (mapActivity != null) {
mapActivity.getContextMenu().close();
if (mapActivity != null && updateUI) {
if (mapActivity.getContextMenu().getObject() == r) {
mapActivity.getContextMenu().close();
}
mapActivity.getMapView().refreshMap();
}
}

View file

@ -213,7 +213,7 @@ public class NotesFragment extends OsmAndListFragment {
Iterator<Recording> it = selected.iterator();
while (it.hasNext()) {
Recording pnt = it.next();
plugin.deleteRecording(pnt);
plugin.deleteRecording(pnt, true);
it.remove();
listAdapter.delete(pnt);
}
@ -505,7 +505,7 @@ public class NotesFragment extends OsmAndListFragment {
builder.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
plugin.deleteRecording(recording);
plugin.deleteRecording(recording, true);
listAdapter.remove(recording);
}
});

View file

@ -327,12 +327,16 @@ public class RoutePreferencesMenu {
btn.setTextColor(btn.getLinkTextColors());
String voiceProvider = settings.VOICE_PROVIDER.get();
String voiceProviderStr;
if (OsmandSettings.VOICE_PROVIDER_NOT_USE.equals(voiceProvider)) {
voiceProviderStr = getString(R.string.shared_string_do_not_use);
if (voiceProvider != null) {
if (OsmandSettings.VOICE_PROVIDER_NOT_USE.equals(voiceProvider)) {
voiceProviderStr = getString(R.string.shared_string_do_not_use);
} else {
voiceProviderStr = FileNameTranslationHelper.getVoiceName(mapActivity, voiceProvider);
}
voiceProviderStr += voiceProvider.contains("tts") ? " TTS" : "";
} else {
voiceProviderStr = FileNameTranslationHelper.getVoiceName(mapActivity, voiceProvider);
voiceProviderStr = getString(R.string.shared_string_not_selected);
}
voiceProviderStr += voiceProvider.contains("tts") ? " TTS" : "";
btn.setText(voiceProviderStr);
btn.setOnClickListener(new View.OnClickListener() {
@Override