Start Android Wear Watchface from Activity - android-activity

I am wondering if it's possible to start the Watchface Service from an activity?
I tried to start the service in the onCreate method of my activity but it does not show the Watchface:
Intent serviceIntent = new Intent(this, CustomWatchFaceService);
startService(serviceIntent);
update
Here is the code for the WatchfaceService
public class CustomWatchFaceService extends CanvasWatchFaceService {
private static final String TAG = "DigitalWatchFaceService";
private static final Typeface BOLD_TYPEFACE =
Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
private static final Typeface NORMAL_TYPEFACE =
Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);
private static final long NORMAL_UPDATE_RATE_MS = 500;
private static final long MUTE_UPDATE_RATE_MS = TimeUnit.MINUTES.toMillis(1);
#Override
public Engine onCreateEngine() {
return new Engine();
}
private class Engine extends CanvasWatchFaceService.Engine {
static final String COLON_STRING = ":";
static final int MUTE_ALPHA = 100;
static final int NORMAL_ALPHA = 255;
static final int MSG_UPDATE_TIME = 0;
long mInteractiveUpdateRateMs = NORMAL_UPDATE_RATE_MS;
final Handler mUpdateTimeHandler = new Handler() {
#Override
public void handleMessage(Message message) {
switch (message.what) {
case MSG_UPDATE_TIME:
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "updating time");
}
invalidate();
if (shouldTimerBeRunning()) {
long timeMs = System.currentTimeMillis();
long delayMs =
mInteractiveUpdateRateMs - (timeMs % mInteractiveUpdateRateMs);
mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);
}
break;
}
}
};
Paint mBackgroundPaint;
Bitmap mBackgroundBitmap;
Bitmap wifiIconOn;
Bitmap wifiIconOff;
Paint mDatePaint;
Paint mNotificationPaint;
Paint mNotificationMax;
Paint mNotificationHigh;
Paint mHourPaint;
Paint mMinutePaint;
Paint mSecondPaint;
Paint mAmPmPaint;
Paint mColonPaint;
float mColonWidth;
boolean mMute;
Calendar mCalendar;
Date mDate;
SimpleDateFormat mDayOfWeekFormat;
java.text.DateFormat mDateFormat;
boolean mShouldDrawColons;
float mXOffset;
float mYOffset;
float mLineHeight;
int mInteractiveBackgroundColor =
R.color.interactive_bg;
int mInteractiveNotificationMax =
R.color.notification_max;
int mInteractiveNotificationHigh =
R.color.notification_high;
int mInteractiveNotificationColor =
R.color.notification;
int mInteractiveHourDigitsColor =
R.color.interactive_time;
int mInteractiveMinuteDigitsColor =
R.color.interactive_time;
int mInteractiveSecondDigitsColor =
R.color.interactive_time;
boolean mLowBitAmbient;
#Override
public void onCreate(SurfaceHolder holder) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onCreate");
}
super.onCreate(holder);
Locale locale = new Locale("de");
Locale.setDefault(locale);
Configuration config = getResources().getConfiguration();
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
setWatchFaceStyle(new WatchFaceStyle.Builder(CustomWatchFaceService.this)
.setCardPeekMode(WatchFaceStyle.PEEK_MODE_VARIABLE)
.setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
.setShowSystemUiTime(false)
.build());
Resources resources = CustomWatchFaceService.this.getResources();
mYOffset = resources.getDimension(R.dimen.digital_y_offset);
mLineHeight = resources.getDimension(R.dimen.digital_line_height);
setInteractiveColors();
// Not sure why the text color needs to be set here again ... it should be set in setDefaultColors()!
mDatePaint.setColor(getColor(R.color.digital_date));
mNotificationPaint.setColor(getColor(R.color.notification));
mNotificationMax.setColor(getColor(R.color.notification_max));
mNotificationHigh.setColor(getColor(R.color.notification_high));
mHourPaint.setColor(getColor(R.color.interactive_time));
mMinutePaint.setColor(getColor(R.color.interactive_time));
mSecondPaint.setColor(getColor(R.color.interactive_time));
mColonPaint.setColor(getColor(R.color.interactive_time));
//Images should be loaded here so they can be called during the Draw Method
wifiIconOn = BitmapFactory.decodeResource(CustomWatchFaceService.this.getResources(), R.drawable.wifi_on_small);
wifiIconOff = BitmapFactory.decodeResource(CustomWatchFaceService.this.getResources(), R.drawable.wifi_off_small);
mBackgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.customcart_logo_240_alpha);
mCalendar = Calendar.getInstance();
mDate = new Date();
initFormats();
}
public void setInteractiveColors() {
mBackgroundPaint = new Paint();
mBackgroundPaint.setColor(getColor(mInteractiveBackgroundColor));
mNotificationPaint = createTextPaint(mInteractiveNotificationColor);
mNotificationMax = createTextPaint(mInteractiveNotificationMax);
mNotificationHigh = createTextPaint(mInteractiveNotificationHigh);
mDatePaint = createTextPaint(R.color.digital_date);
mHourPaint = createTextPaint(mInteractiveHourDigitsColor, BOLD_TYPEFACE);
mMinutePaint = createTextPaint(mInteractiveMinuteDigitsColor);
mSecondPaint = createTextPaint(mInteractiveSecondDigitsColor);
mColonPaint = createTextPaint(R.color.digital_colons);
}
#Override
public void onDestroy() {
mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
super.onDestroy();
}
private Paint createTextPaint(int defaultInteractiveColor) {
return createTextPaint(defaultInteractiveColor, NORMAL_TYPEFACE);
}
private Paint createTextPaint(int defaultInteractiveColor, Typeface typeface) {
Paint paint = new Paint();
paint.setColor(defaultInteractiveColor);
paint.setTypeface(typeface);
paint.setAntiAlias(true);
return paint;
}
#Override
public void onVisibilityChanged(boolean visible) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onVisibilityChanged: " + visible);
}
super.onVisibilityChanged(visible);
updateTimer();
}
private void initFormats() {
mDayOfWeekFormat = new SimpleDateFormat("EEEE", Locale.getDefault());
mDayOfWeekFormat.setCalendar(mCalendar);
mDateFormat = DateFormat.getDateFormat(CustomWatchFaceService.this);
mDateFormat.setCalendar(mCalendar);
}
#Override
public void onApplyWindowInsets(WindowInsets insets) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onApplyWindowInsets: " + (insets.isRound() ? "round" : "square"));
}
super.onApplyWindowInsets(insets);
// Load resources that have alternate values for round watches.
Resources resources = CustomWatchFaceService.this.getResources();
boolean isRound = insets.isRound();
mXOffset = resources.getDimension(isRound
? R.dimen.digital_x_offset_round : R.dimen.digital_x_offset);
float textSize = resources.getDimension(isRound
? R.dimen.digital_text_size_round : R.dimen.digital_text_size);
float notificationTextSize = resources.getDimension(isRound
? R.dimen.notification_text_size : R.dimen.notification_text_size);
mDatePaint.setTextSize(resources.getDimension(R.dimen.digital_date_text_size));
mHourPaint.setTextSize(textSize);
mMinutePaint.setTextSize(textSize);
mSecondPaint.setTextSize(textSize);
mColonPaint.setTextSize(textSize);
mNotificationPaint.setTextSize(notificationTextSize);
mColonWidth = mColonPaint.measureText(COLON_STRING);
}
#Override
public void onPropertiesChanged(Bundle properties) {
super.onPropertiesChanged(properties);
boolean burnInProtection = properties.getBoolean(PROPERTY_BURN_IN_PROTECTION, false);
mHourPaint.setTypeface(burnInProtection ? NORMAL_TYPEFACE : BOLD_TYPEFACE);
mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false);
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onPropertiesChanged: burn-in protection = " + burnInProtection
+ ", low-bit ambient = " + mLowBitAmbient);
}
}
#Override
public void onTimeTick() {
super.onTimeTick();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onTimeTick: ambient = " + isInAmbientMode());
}
invalidate();
}
#Override
public void onAmbientModeChanged(boolean inAmbientMode) {
super.onAmbientModeChanged(inAmbientMode);
if (!isInAmbientMode()) {
mBackgroundPaint = new Paint();
mBackgroundPaint.setColor(getColor(R.color.interactive_bg));
mDatePaint.setColor(getColor(R.color.digital_date));
mHourPaint.setColor(getColor(R.color.interactive_time));
mMinutePaint.setColor(getColor(R.color.interactive_time));
mSecondPaint.setColor(getColor(R.color.interactive_time));
mColonPaint.setColor(getColor(R.color.interactive_time));
}
else {
mBackgroundPaint = new Paint();
mBackgroundPaint.setColor(getColor(R.color.ambient_bg));
mDatePaint.setColor(getColor(R.color.digital_date));
mHourPaint.setColor(getColor(R.color.ambient_time));
mMinutePaint.setColor(getColor(R.color.ambient_time));
mSecondPaint.setColor(getColor(R.color.ambient_time));
mColonPaint.setColor(getColor(R.color.ambient_time));
}
//Log.d("XXX", "onAmbientModeChanged: " + inAmbientMode);
if (mLowBitAmbient) {
boolean antiAlias = !inAmbientMode;
mDatePaint.setAntiAlias(antiAlias);
mHourPaint.setAntiAlias(antiAlias);
mMinutePaint.setAntiAlias(antiAlias);
mSecondPaint.setAntiAlias(antiAlias);
mAmPmPaint.setAntiAlias(antiAlias);
mColonPaint.setAntiAlias(antiAlias);
}
invalidate();
// Whether the timer should be running depends on whether we're in ambient mode (as well
// as whether we're visible), so we may need to start or stop the timer.
updateTimer();
}
#Override
public void onInterruptionFilterChanged(int interruptionFilter) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onInterruptionFilterChanged: " + interruptionFilter);
}
super.onInterruptionFilterChanged(interruptionFilter);
boolean inMuteMode = interruptionFilter == WatchFaceService.INTERRUPTION_FILTER_NONE;
// We only need to update once a minute in mute mode.
setInteractiveUpdateRateMs(inMuteMode ? MUTE_UPDATE_RATE_MS : NORMAL_UPDATE_RATE_MS);
if (mMute != inMuteMode) {
mMute = inMuteMode;
int alpha = inMuteMode ? MUTE_ALPHA : NORMAL_ALPHA;
mDatePaint.setAlpha(alpha);
mHourPaint.setAlpha(alpha);
mMinutePaint.setAlpha(alpha);
mColonPaint.setAlpha(alpha);
mAmPmPaint.setAlpha(alpha);
invalidate();
}
}
public void setInteractiveUpdateRateMs(long updateRateMs) {
if (updateRateMs == mInteractiveUpdateRateMs) {
return;
}
mInteractiveUpdateRateMs = updateRateMs;
// Stop and restart the timer so the new update rate takes effect immediately.
if (shouldTimerBeRunning()) {
updateTimer();
}
}
private String formatTwoDigitNumber(int hour) {
return String.format("%02d", hour);
}
#Override
public void onDraw(Canvas canvas, Rect bounds) {
long now = System.currentTimeMillis();
int width = bounds.width();
int height = bounds.height();
mCalendar.setTimeInMillis(now);
mDate.setTime(now);
boolean is24Hour = DateFormat.is24HourFormat(CustomWatchFaceService.this);
// Draw the background.
canvas.drawRect(0, 0, bounds.width(), bounds.height(), mBackgroundPaint);
//Draw the background Image
if (mBackgroundBitmap == null
|| mBackgroundBitmap.getWidth() != width
|| mBackgroundBitmap.getHeight() != height) {
mBackgroundBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
width, height, true /* filter */);
}
//Log.d("XXX", "Width: "+ mBackgroundBitmap.getWidth() + "Height: "+mBackgroundBitmap.getHeight() );
if (isInAmbientMode() && (mLowBitAmbient)) {
canvas.drawColor(Color.BLACK);
} else if (isInAmbientMode()) {
canvas.drawColor(Color.BLACK);
} else {
canvas.drawBitmap(mBackgroundBitmap, 0, 0, mBackgroundPaint);
}
// Show colons for the first half of each second so the colons blink on when the time updates.
mShouldDrawColons = (System.currentTimeMillis() % 1000) < 500;
// Draw the hours.
float x = mXOffset;
String hourString;
if (is24Hour) {
hourString = formatTwoDigitNumber(mCalendar.get(Calendar.HOUR_OF_DAY));
} else {
int hour = mCalendar.get(Calendar.HOUR);
if (hour == 0) {
hour = 12;
}
hourString = String.valueOf(hour);
}
canvas.drawText(hourString, x, mYOffset, mHourPaint);
x += mHourPaint.measureText(hourString);
// In ambient and mute modes, always draw the first colon. Otherwise, draw the
// first colon for the first half of each second.
if (isInAmbientMode() || mMute || mShouldDrawColons) {
canvas.drawText(COLON_STRING, x, mYOffset, mColonPaint);
}
x += mColonWidth;
// Draw the minutes.
String minuteString = formatTwoDigitNumber(mCalendar.get(Calendar.MINUTE));
canvas.drawText(minuteString, x, mYOffset, mMinutePaint);
x += mMinutePaint.measureText(minuteString);
// In unmuted interactive mode, draw a second blinking colon followed by the seconds.
// Otherwise, if we're in 12-hour mode, draw AM/PM
if (!isInAmbientMode() && !mMute) {
if (mShouldDrawColons) {
canvas.drawText(COLON_STRING, x, mYOffset, mColonPaint);
}
x += mColonWidth;
canvas.drawText(formatTwoDigitNumber(
mCalendar.get(Calendar.SECOND)), x, mYOffset, mSecondPaint);
} else if (!is24Hour) {
x += mColonWidth;
}
// Only render the day of week and date if there is no peek card, so they do not bleed
// into each other in ambient mode.
if (getPeekCardPosition().isEmpty()) {
// Day of week
canvas.drawText(
mDayOfWeekFormat.format(mDate),
mXOffset, mYOffset + mLineHeight, mDatePaint);
// Date
canvas.drawText(
mDateFormat.format(mDate),
mXOffset, mYOffset + mLineHeight * 2, mDatePaint);
}
}
/**
* Starts the {#link #mUpdateTimeHandler} timer if it should be running and isn't currently
* or stops it if it shouldn't be running but currently is.
*/
private void updateTimer() {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "updateTimer");
}
mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
if (shouldTimerBeRunning()) {
mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME);
}
}
/**
* Returns whether the {#link #mUpdateTimeHandler} timer should be running. The timer should
* only run when we're visible and in interactive mode.
*/
private boolean shouldTimerBeRunning() {
return isVisible() && !isInAmbientMode();
}
}
}

Related

Camera 2 api full screen not to stretch

private static final int SENSOR_ORIENTATION_DEFAULT_DEGREES = 90;
private static final int SENSOR_ORIENTATION_INVERSE_DEGREES = 270;
private static final SparseIntArray DEFAULT_ORIENTATIONS = new SparseIntArray();
private static final SparseIntArray INVERSE_ORIENTATIONS = new SparseIntArray();
private static final long DELAY = 1000;
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
private long startTime = 0L;
int num = 1;
List<VideoModel> videoList;
private Handler customHandler = new Handler();
private static final String TAG = "RecordVideoActivity";
private String videoName;
static {
DEFAULT_ORIENTATIONS.append(Surface.ROTATION_0, 90);
DEFAULT_ORIENTATIONS.append(Surface.ROTATION_90, 0);
DEFAULT_ORIENTATIONS.append(Surface.ROTATION_180, 270);
DEFAULT_ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
static {
INVERSE_ORIENTATIONS.append(Surface.ROTATION_0, 270);
INVERSE_ORIENTATIONS.append(Surface.ROTATION_90, 180);
INVERSE_ORIENTATIONS.append(Surface.ROTATION_180, 90);
INVERSE_ORIENTATIONS.append(Surface.ROTATION_270, 0);
}
private AutoFitTextureView mTextureView;
private ImageButton mRecordButton;
private ImageView mDots;
private ImageButton mCheckPoint;
private CameraDevice mCameraDevice;
private CameraCaptureSession mPreviewSession;
private TextureView.SurfaceTextureListener mSurfaceTextureListener
= new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
int width, int height) {
openCamera(width, height);
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture,
int width, int height) {
configureTransform(width, height);
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return true;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
private Size mPreviewSize;
private Size mVideoSize;
private MediaRecorder mMediaRecorder;
private boolean mIsRecordingVideo;
private HandlerThread mBackgroundThread;
private Handler mBackgroundHandler;
private Semaphore mCameraOpenCloseLock = new Semaphore(1);
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice cameraDevice) {
mCameraDevice = cameraDevice;
startPreview();
mCameraOpenCloseLock.release();
if (null != mTextureView) {
configureTransform(mTextureView.getWidth(), mTextureView.getHeight());
}
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int error) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
finish();
}
};
private Integer mSensorOrientation;
private String mNextVideoAbsolutePath;
private CaptureRequest.Builder mPreviewBuilder;
private CameraManager manager;
private String cameraId;
private boolean isFlashSupported;
private ImageButton flashButton;
private ImageButton switchCamera;
private ImageButton revertVideo;
public static final String CAMERA_BACK = "0";
private TextView mChronometer;
private String flashOpt;
private long lastSavedTime;
private String prepend;
private static Size chooseVideoSize(Size[] choices) {
for (Size size : choices) {
if (size.getWidth() == size.getHeight() * 4 / 3 && size.getWidth() <= 1080) {
return size;
}
}
Log.e(TAG, "Couldn't find any suitable video size");
return choices[choices.length - 1];
}
private static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) {
// Collect the supported resolutions that are at least as big as the preview Surface
List<Size> bigEnough = new ArrayList<>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
for (Size option : choices) {
if (option.getHeight() == option.getWidth() * h / w &&
option.getWidth() >= width && option.getHeight() >= height) {
bigEnough.add(option);
}
}
// Pick the smallest of those, assuming we found any
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizesByArea());
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera2_video_image);
File dir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES) + File.separator + AppConstants.APPDIRRECORDING);
if (dir.isDirectory()) {
deleteDirectory(dir);
}
videoList = new ArrayList<>();
mTextureView = findViewById(R.id.textureView);
mRecordButton = findViewById(R.id.videoOnlineImageButton);
mRecordButton.setImageResource(R.drawable.ic_video);
mCheckPoint = findViewById(R.id.checkPoint);
mCheckPoint.setVisibility(View.GONE);
mDots = findViewById(R.id.dot);
mRecordButton.setOnClickListener(this);
flashButton = findViewById(R.id.flashVideo);
switchCamera = findViewById(R.id.switchVideo);
revertVideo = findViewById(R.id.revertVideo);
revertVideo.setVisibility(View.GONE);
mChronometer = findViewById(R.id.chronometer);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
flashOpt = prefs.getString(getString(R.string.flash_option), getString(R.string.auto));
if (flashOpt.equals(getString(R.string.flash_off)))
flashButton.setImageResource(R.drawable.flash_auto);
else if (flashOpt.equals(getString(R.string.flash_on)))
flashButton.setImageResource(R.drawable.flash_on);
else
flashButton.setImageResource(R.drawable.flash_off);
findViewById(R.id.checkPoint).setOnClickListener(this);
findViewById(R.id.flashVideo).setOnClickListener(this);
findViewById(R.id.switchVideo).setOnClickListener(this);
findViewById(R.id.revertVideo).setOnClickListener(this);
}
#Override
public void onResume() {
super.onResume();
startBackgroundThread();
if (mTextureView.isAvailable()) {
openCamera(mTextureView.getWidth(), mTextureView.getHeight());
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
if(mIsRecordingVideo)
mRecordButton.setImageResource(R.drawable.ic_video_stop);
else
mRecordButton.setImageResource(R.drawable.ic_video);
mCheckPoint.setEnabled(true);
startTime=SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
}
#Override
public void onPause() {
closeCamera();
mCheckPoint.setEnabled(false);
timeSwapBuff += timeInMilliseconds;
customHandler.removeCallbacks(updateTimerThread);
stopBackgroundThread();
super.onPause();
}
private Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int hour = mins / 60;
mChronometer.setText("" + hour + ":"
+ String.format("%02d", mins) + ":"
+ String.format("%02d", secs));
customHandler.postDelayed(this, 0);
}
};
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.videoOnlineImageButton: {
if (mIsRecordingVideo) {
mDots.setVisibility(View.GONE);
mChronometer.setVisibility(View.GONE);
switchCamera.setVisibility(View.VISIBLE);
mCheckPoint.setVisibility(View.GONE);
stopRecordingVideo();
Intent mediaStoreUpdateIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaStoreUpdateIntent.setData(Uri.fromFile(new File(mNextVideoAbsolutePath)));
sendBroadcast(mediaStoreUpdateIntent);
} else {
mCheckPoint.setVisibility(View.VISIBLE);
switchCamera.setVisibility(View.GONE);
mChronometer.setVisibility(View.VISIBLE);
mDots.setVisibility(View.VISIBLE);
startRecordingVideo();
}
break;
}
case R.id.switchVideo: {
facingCamera = !facingCamera;
closeCamera();
if (mTextureView.isAvailable()) {
openCamera(mTextureView.getWidth(), mTextureView.getHeight());
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
break;
}
case R.id.flashVideo: {
if (onFlashCheck()) {
CameraCharacteristics cameraCharacteristics = null;
try {
cameraCharacteristics = manager.getCameraCharacteristics(cameraId);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Boolean available = cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
isFlashSupported = available == null ? false : available;
switchFlash();
}
break;
}
}
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("CameraBackground");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#SuppressLint("MissingPermission")
private void openCamera(int width, int height) {
final Activity activity = this;
if (null == activity || activity.isFinishing()) {
return;
}
manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
try {
Log.d(TAG, "tryAcquire");
if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
cameraId = manager.getCameraIdList()[1];
if (facingCamera) {
cameraId = manager.getCameraIdList()[1];
flashButton.setVisibility(View.GONE);
} else {
cameraId = manager.getCameraIdList()[0];
flashButton.setVisibility(View.VISIBLE);
}
// Choose the sizes for camera preview and video recording
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics
.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
if (map == null) {
throw new RuntimeException("Cannot get available preview/video sizes");
}
mVideoSize = chooseVideoSize(map.getOutputSizes(MediaRecorder.class));
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
width, height, mVideoSize);
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight());
} else {
mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());
}
configureTransform(width, height);
mMediaRecorder = new MediaRecorder();
manager.openCamera(cameraId, mStateCallback, null);
} catch (CameraAccessException e) {
Toast.makeText(activity, "Cannot access the camera.", Toast.LENGTH_SHORT).show();
activity.finish();
} catch (NullPointerException e) {
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera opening.");
}
}
private void closeCamera() {
try {
mCameraOpenCloseLock.acquire();
closePreviewSession();
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
if (null != mMediaRecorder) {
mMediaRecorder.release();
mMediaRecorder = null;
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera closing.");
} finally {
mCameraOpenCloseLock.release();
}
}
private void startPreview() {
if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) {
return;
}
try {
closePreviewSession();
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
Surface previewSurface = new Surface(texture);
mPreviewBuilder.addTarget(previewSurface);
mCameraDevice.createCaptureSession(Collections.singletonList(previewSurface),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession session) {
mPreviewSession = session;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession session) {
Toast.makeText(RecordVideoActivity.this, "Failed", Toast.LENGTH_SHORT).show();
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updatePreview() {
if (null == mCameraDevice) {
return;
}
try {
setUpCaptureRequestBuilder(mPreviewBuilder);
HandlerThread thread = new HandlerThread("CameraPreview");
thread.start();
mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void setUpCaptureRequestBuilder(CaptureRequest.Builder builder) {
if (onFlashCheck()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
flashButton.setVisibility(View.VISIBLE);
}
});
if (flashOpt.equals(getString(R.string.auto)))
builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
else if (flashOpt.equals(getString(R.string.flash_off)))
builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
else
builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
} else
runOnUiThread(new Runnable() {
#Override
public void run() {
flashButton.setVisibility(View.GONE);
}
});
}
private void configureTransform(int viewWidth, int viewHeight) {
if (null == mTextureView || null == mPreviewSize) {
return;
}
int rotation = getWindowManager().getDefaultDisplay().getRotation();
Matrix matrix = new Matrix();
RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
float centerX = viewRect.centerX();
float centerY = viewRect.centerY();
if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
float scale = Math.max(
(float) viewHeight / mPreviewSize.getHeight(),
(float) viewWidth / mPreviewSize.getWidth());
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(90 * (rotation - 2), centerX, centerY);
}
mTextureView.setTransform(matrix);
}
private void setUpMediaRecorder() throws IOException {
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
File file = getVideoFilePath(this);
mNextVideoAbsolutePath = file.getAbsolutePath();
videoName = file.getName();
mMediaRecorder.setOutputFile(mNextVideoAbsolutePath);
mMediaRecorder.setVideoEncodingBitRate(10000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
int rotation = getWindowManager().getDefaultDisplay().getRotation();
switch (mSensorOrientation) {
case SENSOR_ORIENTATION_DEFAULT_DEGREES:
mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
break;
case SENSOR_ORIENTATION_INVERSE_DEGREES:
mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
break;
}
mMediaRecorder.prepare();
}
private File getVideoFilePath(Context context) {
File appDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES) + File.separator + AppConstants.APPDIRRECORDING);
if (!appDir.isDirectory()) {
appDir.mkdirs();
}
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String prepend = "VIDEO_" + timestamp + ".mp4";
File videoFile = null;
try {
videoFile = File.createTempFile(prepend, ".mp4", appDir);
} catch (IOException e) {
e.printStackTrace();
}
return videoFile;
}
private void startRecordingVideo() {
if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) {
return;
}
try {
closePreviewSession();
setUpMediaRecorder();
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
List<Surface> surfaces = new ArrayList<>();
// Set up Surface for the camera preview
Surface previewSurface = new Surface(texture);
surfaces.add(previewSurface);
mPreviewBuilder.addTarget(previewSurface);
// Set up Surface for the MediaRecorder
Surface recorderSurface = mMediaRecorder.getSurface();
surfaces.add(recorderSurface);
mPreviewBuilder.addTarget(recorderSurface);
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull final CameraCaptureSession cameraCaptureSession) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mPreviewSession = cameraCaptureSession;
updatePreview();
mIsRecordingVideo = true;
startTime = SystemClock.uptimeMillis();
mChronometer.setVisibility(View.VISIBLE);
customHandler.postDelayed(updateTimerThread, 0);
mRecordButton.setImageResource(R.drawable.ic_video_stop);
mMediaRecorder.start();
mCheckPoint.setEnabled(true);
}
});
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(RecordVideoActivity.this, "Failed", Toast.LENGTH_SHORT).show();
}
}, mBackgroundHandler);
} catch (CameraAccessException | IOException e) {
e.printStackTrace();
}
}
private void closePreviewSession() {
if (mPreviewSession != null) {
mPreviewSession.close();
mPreviewSession = null;
}
}
#SuppressLint("ResourceType")
private void stopRecordingVideo() {
mIsRecordingVideo = false;
customHandler.removeCallbacks(updateTimerThread);
mRecordButton.setImageResource(R.drawable.ic_video);
if(mMediaRecorder!=null) {
try {
mMediaRecorder.stop();
} catch (RuntimeException e) {
e.printStackTrace();
}
mMediaRecorder.reset();
}
}
static class CompareSizesByArea implements Comparator<Size> {
#Override
public int compare(Size lhs, Size rhs) {
return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
(long) rhs.getWidth() * rhs.getHeight());
}
}
#Override
protected void onDestroy() {
customHandler.removeCallbacks(updateTimerThread);
}
I have implemented following coding in my app.i used camera 2 api for video recording.i feel that video streaming is stretched. mainly when i switch camera into front one.pls help me to resolve this problem
I have implemented following coding in my app.i used camera 2 api for video recording.i feel that video streaming is stretched. mainly when i switch camera into front one.pls help me to resolve this problem
Change aspect ratio values in AutoFitTextureView class or use Textureview instead of AutoFitTextureview.

google map android api application crash on getMapAsync()

Process:*****.googlemapapp, PID: 2402
java.lang.UnsatisfiedLinkError: Couldn't load rocket from loader bvt[DexPathList[[zip file "/data/data/com.google.android.gms/app_chimera/m/00000003/DynamiteModulesB_GmsCore_prod_alldpi_release.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]]: findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:358)
at java.lang.System.loadLibrary(System.java:526)
at com.google.maps.api.android.lib6.rocket.a.onSurfaceCreated(:com.google.android.gms.DynamiteModulesB:119)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1501)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
i m Getting an error when i run my mapFragment.getMapAsync(this)
i works very well for first time ...when i start again its giving error like above ...everything works well for first time ....it is like for odd it works for even application crashesh.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = MapsActivity.this;
setContentView(R.layout.activity_maps);
MarkerPoints = new ArrayList<>();
nextBtn = (Button) findViewById(R.id.nextBtn);
txtDistance = (TextView) findViewById(R.id.txtDistance);
txtCheckpoint = (TextView) findViewById(R.id.txtCheckpoint);
txtDistance.setText("Distance Travel : 0 Mtr");
distance = new ArrayList<Float>();
waypoints = new ArrayList<LatLng>();
Intent i = getIntent();
Places place = (Places) i.getParcelableExtra("data");
Log.d("data", place.toString());
startPoint = place.startPoint;
endPoint = place.endPoint;
waypoints=place.waypoints;
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resultCode == ConnectionResult.SUCCESS)
{
if(mapFragment != null) {
mapFragment.getMapAsync(this);
}
}else
Toast.makeText(context, "UnAvailable", Toast.LENGTH_SHORT).show();
}
//here application crashes on alternative run on mapFragment.getMapAsync(this) ,
all code works fine for first time on second time it says
java.lang.UnsatisfiedLinkError: Couldn't load rocket from loader bvt[DexPathList[[zip file "/data/data/com.google.android.gms/app_chimera/m/00000003/DynamiteModulesB_GmsCore_prod_alldpi_release.apk"],
nativeLibraryDirectories=[/vendor/lib, /system/lib]]]:
findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:358)
//i initialize maps and then according to location i change panoroma image, here Fetchurl will save the path data in routes which is List<List<HashMap<String, String>>> it is Asynchronous call
#Override
public void onMapReady(GoogleMap googleMap) {
try {
mMap = googleMap;
MarkerPoints.add(startPoint);
startMarker.position(startPoint);
startMarker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
m = mMap.addMarker(startMarker);
m.setTitle("You");
m.showInfoWindow();
MarkerPoints.add(endPoint);
endMarker.position(endPoint);
endMarker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
Marker e = mMap.addMarker(endMarker);
e.setTitle("Goal");
LatLng origin = MarkerPoints.get(0);
LatLng dest = MarkerPoints.get(1);
String url = getUrl(origin, dest);
FetchUrl FetchUrl = new FetchUrl();
FetchUrl.execute(url);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(startPoint));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
initializeSteatView();
} catch (Exception e) {
}
}`
///here i initialize streatview
` public void initializeSteatView() {
SupportStreetViewPanoramaFragment streetViewPanoramaFragment =
(SupportStreetViewPanoramaFragment)
getSupportFragmentManager().findFragmentById(R.id.mapPanaroma);
streetViewPanoramaFragment.getStreetViewPanoramaAsync(
new OnStreetViewPanoramaReadyCallback() {
#Override
public void onStreetViewPanoramaReady(final StreetViewPanorama panorama) {
panorama.setUserNavigationEnabled(false);
panorama.setPosition(startPoint);
nextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!isRouteLoaded)return;
if (currentPosition == routes.get(0).size() - 1) return;
if (currentPosition == 0) {
String s1 = routes.get(0).get(currentPosition).get("lat");
String s2 = routes.get(0).get(currentPosition).get("lng");
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
LatLng newPosition = new LatLng(d1, d2);
mMap.moveCamera(CameraUpdateFactory.newLatLng(newPosition));
mMap.animateCamera(CameraUpdateFactory.zoomTo(17));
panorama.setPosition(newPosition);
m.setPosition(newPosition);
distance.add(totalDistance);
for (int i = 1; i < routes.get(0).size(); i++) {
d1 = Double.parseDouble(routes.get(0).get(i - 1).get("lat"));
d2 = Double.parseDouble(routes.get(0).get(i - 1).get("lng"));
LatLng start = new LatLng(d1, d2);
d1 = Double.parseDouble(routes.get(0).get(i).get("lat"));
d2 = Double.parseDouble(routes.get(0).get(i).get("lng"));
LatLng end = new LatLng(d1, d2);
totalDistance += calculateDistance(start, end);
distance.add(totalDistance);
Log.d("distance", distance.toString());
}
final Handler handler = new Handler();
final TimerTask timertask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
distanceTravel++;
txtDistance.setText("Distance Travel : " + distanceTravel + " Mtr");
checkDistance();
}
});
}
};
Timer timer = new Timer();
timer.schedule(timertask, 0, 500);
}
}
public void checkDistance() {
if (currentPosition == routes.get(0).size() - 1) return;
checkPoint = distance.get(currentPosition + 1);
txtCheckpoint.setText("Checkpoint : " + checkPoint);
if (checkPoint < Float.parseFloat(distanceTravel + "")) {
currentPosition++;
} else {
return;
}
String s1 = routes.get(0).get(currentPosition).get("lat");
String s2 = routes.get(0).get(currentPosition).get("lng");
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
LatLng newPosition = new LatLng(d1, d2);
mMap.moveCamera(CameraUpdateFactory.newLatLng(newPosition));
mMap.animateCamera(CameraUpdateFactory.zoomTo(17));
panorama.setPosition(newPosition);
m.setPosition(newPosition);
}
});
panorama.setOnStreetViewPanoramaChangeListener(new StreetViewPanorama.OnStreetViewPanoramaChangeListener() {
#Override
public void onStreetViewPanoramaChange(StreetViewPanoramaLocation streetViewPanoramaLocation) {
if(!isRouteLoaded)return;
if (routes.size() > 0) {
double lat1 = Double.parseDouble(routes.get(0).get(currentPosition).get("lat"));
double lng1 = Double.parseDouble(routes.get(0).get(currentPosition).get("lng"));
double lat2 = Double.parseDouble(routes.get(0).get
(currentPosition + 1).get("lat"));
double lng2 = Double.parseDouble(routes.get(0).get
(currentPosition + 1).get("lng"));
double dLon = (lng2 - lng1);
double y = Math.sin(dLon) * Math.cos(lat2);
double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
double brng = Math.toDegrees((Math.atan2(y, x)));
// brng = (360 - ((brng + 360) % 360));
long duration = 1000;
StreetViewPanoramaCamera camera =
new StreetViewPanoramaCamera.Builder()
.zoom(panorama.getPanoramaCamera().zoom)
.tilt(panorama.getPanoramaCamera().tilt)
.bearing(Float.parseFloat(brng + ""))
.build();
panorama.animateTo(camera, duration);
}
}
});
}
});
}
`

How to limit a float to give one or no value after the decimal

I'm working in Eclipse and using float for my variables and values. The only issue I am getting is the huge number of digits (1.563524354) after the decimal. Can I somehow limit them to one digit after the decimal like (1.5) or no digit or decimal at all simply like 1. ?
My code:
float nCurrentSpeed;
private long startTime;
private int count;
private int pointAverage;
private Float nMaxSpeed = 0F;
DecimalFormat df = new DecimalFormat("#");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocationManager lm = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
this.onLocationChanged(null);
}
#Override
public void onLocationChanged(Location location) {
TextView tv = (TextView) findViewById(R.id.textView1);
TextView tvd = (TextView) findViewById(R.id.textView5);
if (location == null) {
startTime = System.currentTimeMillis();
count = 0;
pointAverage = 0;
actualizeTextField();
tv.setText("0.0");
} else {
nCurrentSpeed = location.getSpeed();
tv.setText(nCurrentSpeed + "");
count += 1;
pointAverage += location.getSpeed();
actualizeTextField();
if (nMaxSpeed < nCurrentSpeed) {
nMaxSpeed = nCurrentSpeed;
}
}
tvd.setText(nMaxSpeed.toString());
}
private void actualizeTextField() {
// TODO Auto-generated method stub
TextView tf = (TextView) findViewById(R.id.textView3);
if (count > 0) {
long timeOver = System.currentTimeMillis() - startTime;
tf.setText(String.valueOf(pointAverage / (timeOver / 1000)));
} else {
tf.setText("0.0");
}
}
DecimalFormat df = new DecimalFormat("#.#");
df.format(0.91231);
returns:
0.9
If you don't want decimal places, why don't you cast it to int then?
Like this :
double d = 1.234567;
DecimalFormat df1 = new DecimalFormat("#.##"); // set your format
System.out.print(df1.format(d))
If you don't need point values, why are you using float? Check this one.
float nCurrentSpeed;
private long startTime;
private int count;
private int pointAverage;
private int nMaxSpeed = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocationManager lm = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
this.onLocationChanged(null);
}
#Override
public void onLocationChanged(Location location) {
TextView tv = (TextView) findViewById(R.id.textView1);
TextView tvd = (TextView) findViewById(R.id.textView5);
if (location == null) {
startTime = System.currentTimeMillis();
count = 0;
pointAverage = 0;
actualizeTextField();
tv.setText("0.0");
} else {
nCurrentSpeed = location.getSpeed();
tv.setText(nCurrentSpeed + "");
count += 1;
pointAverage += location.getSpeed();
actualizeTextField();
if (nMaxSpeed < nCurrentSpeed) {
nMaxSpeed = (int)nCurrentSpeed;
}
}
tvd.setText(String.valueOf(nMaxSpeed));
}
private void actualizeTextField() {
// TODO Auto-generated method stub
TextView tf = (TextView) findViewById(R.id.textView3);
if (count > 0) {
long timeOver = System.currentTimeMillis() - startTime;
tf.setText(String.valueOf(pointAverage / (timeOver / 1000)));
} else {
tf.setText("0.0");
}
}

Blackberry how to design the Screen like grid view

I am very new to blackberry development and i don't even know how to start. I already read some part of it from it's official site
http://developer.blackberry.com/devzone/files/design/bb7/UI_Guidelines_BlackBerry_Smartphones_7_1.pdf
and other so many link, but i can not post all the link as it is saying thay if you want to post more links then you must have 10 reputation and i dont have that so sorry for that,
Now my question is i want to design layout like this http://postimg.org/image/we3leycsd/
How can i design exactly this kind of layout. I am using eclipse for Blackberry development.
Please help i already tried many things but i am not able to achieve this.
Your any kind of help would be appreciated. Thank you in advance.
I'd create a custom HorizontalFieldManager with n VerticalFieldManagers inside, then override the add and delete methods. Here is something I made before, that should work for you, it adds the new fields to the shortest column.
StaggeredListView.java:
public class StaggeredListView extends HorizontalFieldManager
{
private int column_spacing = 0;
public StaggeredListView(int columns)
{
super(VERTICAL_SCROLL | VERTICAL_SCROLLBAR | NO_HORIZONTAL_SCROLL | NO_HORIZONTAL_SCROLLBAR | USE_ALL_WIDTH);
if (columns < 1)
{
throw new RuntimeException("Number of columns needs to be larger than 0.");
}
final int width = Display.getWidth() / columns;
for (int i = 0; i < columns; i++)
{
VerticalFieldManager vfm = new VerticalFieldManager(NO_VERTICAL_SCROLL | NO_VERTICAL_SCROLLBAR | NO_HORIZONTAL_SCROLL | NO_HORIZONTAL_SCROLLBAR)
{
protected void sublayout(int maxWidth, int maxHeight)
{
maxWidth = Math.min(width, getPreferredWidth());
maxHeight = Math.min(maxHeight, getPreferredHeight());
super.sublayout(width, maxHeight);
super.setExtent(width, maxHeight);
}
};
super.add(vfm);
}
}
public int getColumnCount()
{
return getFieldCount();
}
/**
* Sets the spacing between columns.
*
* <p>
* Spacing between fields is <i><b>not</b></i> set.
* </p>
*/
public void setColumnSpacing(int spacing)
{
if (spacing < 0) throw new RuntimeException("Column spacing my not be negative.");
int length = getColumnCount();
for (int i = 1; i < length; i++)
{
((VerticalFieldManager) getField(i)).setPadding(0, 0, 0, spacing);
}
column_spacing = spacing;
}
/**
* Get the value currently assigned via the {#link #setColumnSpacing(int)} method.
*
* #return
*/
public int getColumnSpacing()
{
return column_spacing;
}
/**
* Deletes all fields from each of the columns.
*/
public void clear()
{
int length = getColumnCount();
for (int i = 0; i < length; i++)
{
((VerticalFieldManager) getField(i)).deleteAll();
}
}
/**
* Delete specified field from the columns.
*
* <p>
* Does <b><i>not</i></b> rearrange fields.
* </p>
*/
public void delete(Field field)
{
int length = getColumnCount();
for (int i = 0; i < length; i++)
{
try
{
((VerticalFieldManager) getField(i)).delete(field);
break;
} catch (IllegalArgumentException e)
{
// field not in this manager
}
}
}
/**
* Adds the field to the column with the least height.
*/
public void add(Field field)
{
// find the vfm with least height
int index = 0;
int height = ((VerticalFieldManager) getField(index)).getPreferredHeight();
int length = getColumnCount();
for (int i = 1; i < length; i++)
{
int temp_height = ((VerticalFieldManager) getField(i)).getPreferredHeight();
if (temp_height < height)
{
height = temp_height;
index = i;
}
}
((VerticalFieldManager) getField(index)).add(field);
}
}
As for the item's contained in it, I'd create a field with an image and text, then paint it myself (I've had a lot of issues with focus and find it easier just to use paint).
You can use this to make a BaseButton http://developer.blackberry.com/bbos/java/documentation/tutorial_create_custom_button_1969896_11.html
BaseButton.java:
public abstract class BaseButton extends Field
{
// flags to indicate the current visual state
protected boolean _visible = true;
protected boolean _active;
protected boolean _focus;
protected boolean drawfocus = false;
private int touch_top = 0;
private int touch_right = 0;
private int touch_bottom = 0;
private int touch_left = 0;
protected boolean fire_on_click = true; // false fires on unclick
public BaseButton()
{
this(0);
}
public BaseButton(long style)
{
super((style & Field.NON_FOCUSABLE) == Field.NON_FOCUSABLE ? style : style | Field.FOCUSABLE);
}
/**
* Sets the radius around the button to trigger touch events.
* <p>
* (0,0,0,0) by default.
* </p>
*/
public void setTouchRadius(int top, int right, int bottom, int left)
{
touch_top = top;
touch_right = right;
touch_bottom = bottom;
touch_left = left;
}
protected void onFocus(int direction)
{
_focus = true;
invalidate();
super.onFocus(direction);
}
protected void onUnfocus()
{
if (_active || _focus)
{
_focus = false;
_active = false;
invalidate();
}
super.onUnfocus();
}
public void set_visible(boolean visible)
{
_visible = visible;
invalidate();
}
public boolean is_visible()
{
return _visible;
}
protected void drawFocus(Graphics g, boolean on)
{
if (drawfocus) super.drawFocus(g, on);
}
protected void layout(int width, int height)
{
setExtent(Math.min(width, getPreferredWidth()), Math.min(height, getPreferredHeight()));
}
protected boolean keyUp(int keycode, int time)
{
if (Keypad.map(Keypad.key(keycode), Keypad.status(keycode)) == Characters.ENTER)
{
_active = false;
invalidate();
return true;
}
return false;
}
protected boolean keyDown(int keycode, int time)
{
if (Keypad.map(Keypad.key(keycode), Keypad.status(keycode)) == Characters.ENTER)
{
_active = true;
invalidate();
}
return super.keyDown(keycode, time);
}
protected boolean keyChar(char character, int status, int time)
{
if (character == Characters.ENTER)
{
clickButton();
return true;
}
return super.keyChar(character, status, time);
}
protected boolean navigationClick(int status, int time)
{
if (status != 0)
{ // non-touch event
_active = true;
invalidate();
if (fire_on_click) clickButton();
}
return true;
}
protected boolean trackwheelClick(int status, int time)
{
if (status != 0)
{ // non-touch event
_active = true;
invalidate();
if (fire_on_click) clickButton();
}
return true;
}
protected boolean navigationUnclick(int status, int time)
{
if (status != 0)
{ // non-touch event
_active = false;
invalidate();
if (!fire_on_click) clickButton();
}
return true;
}
protected boolean trackwheelUnclick(int status, int time)
{
if (status != 0)
{ // non-touch event
_active = false;
invalidate();
if (!fire_on_click) clickButton();
}
return true;
}
protected boolean invokeAction(int action)
{
switch (action)
{
case ACTION_INVOKE :
{
clickButton();
return true;
}
}
return super.invokeAction(action);
}
protected boolean touchEvent(TouchEvent message)
{
boolean isOutOfBounds = touchEventOutOfBounds(message);
switch (message.getEvent())
{
case TouchEvent.CLICK :
if (!_active)
{
_active = true;
invalidate();
}
if (!isOutOfBounds)
{
if (fire_on_click) clickButton();
return true;
}
case TouchEvent.DOWN :
if (!isOutOfBounds)
{
if (!_active)
{
_active = true;
invalidate();
}
return true;
}
return false;
case TouchEvent.UNCLICK :
if (_active)
{
_active = false;
invalidate();
}
if (!isOutOfBounds)
{
if (!fire_on_click) clickButton();
return true;
}
case TouchEvent.UP :
if (_active)
{
_active = false;
invalidate();
}
default :
return false;
}
}
private boolean touchEventOutOfBounds(TouchEvent message)
{
int x = message.getX(1);
int y = message.getY(1);
return (x < 0 - touch_left || y < 0 - touch_top || x > getWidth() + touch_right || y > getHeight() + touch_bottom);
}
public void setDirty(boolean dirty)
{
}
public void setMuddy(boolean muddy)
{
}
public void clickButton()
{
if (_visible) fieldChangeNotify(0);
}
}
ImageSubtitleButton.java:
public class ImageSubtitleButton extends BaseButton
{
private static final int FOCUS_THINKNESS = 2;
String title;
Bitmap image_default;
int height;
public ImageSubtitleButton(String title, String image_default)
{
this.image_default = Bitmap.getBitmapResource(image_default);
setTitle(title);
}
public void setTitle(String title)
{
this.title = title;
height = image_default.getHeight() + getFont().getHeight() + (FOCUS_THINKNESS * 2);
updateLayout();
invalidate();
}
public int getPreferredWidth()
{
return Math.max(getFont().getAdvance(title), image_default.getWidth());
}
public int getPreferredHeight()
{
return height;
}
protected void paint(Graphics graphics)
{
int x = (getWidth() - image_default.getWidth()) / 2;
int y = 0;
graphics.drawBitmap(x, y, image_default.getWidth(), image_default.getHeight(), image_default, 0, 0);
if (_focus)
{
graphics.setColor(Color.BLUE); // your focus colour
for (int i = 0; i < FOCUS_THINKNESS; i++)
{
graphics.drawRect(x + i, y + i, image_default.getWidth() - (i * 2), image_default.getHeight() - (i * 2));
}
}
graphics.setColor(Color.BLACK);
y = image_default.getHeight();
graphics.drawText(title, x, y);
}
}
Now you can add these to your screen as follows:
StaggedListView listview = new StaggedListView(2);
ImageSubtitleButton button = new ImageSubtitleButton("test", "test.png");
listview.add(button);
add(listview);
You'll need to set the preferred width and height of the ImageSubtitleButton to keep it uniform, as in the example image you posted.
Apologies, I don't have time to create a full answer, but I personally would not use the HFM/VFM combination to do this. Instead use one Manager that provides the Grid. If you are using a late enough level OS you have GridFieldManager that does this,
GridFieldManager
but I have had mixed experiences with that Manager. So I generally use this Manager:
TableLayoutManager
I hope this gets you going.

I am getting error while importing Policymanager?

I am writing code for my own media-controller for VideoView.
and my code is as follows
public class FMediaController extends FrameLayout {
private MediaPlayerControl mPlayer;
private Context mContext;
private View mAnchor;
private View mRoot;
private WindowManager mWindowManager;
private Window mWindow;
private View mDecor;
private ProgressBar mProgress;
private TextView mEndTime, mCurrentTime;
private boolean mShowing;
private boolean mDragging;
private static final int sDefaultTimeout = 3000;
private static final int FADE_OUT = 1;
private static final int SHOW_PROGRESS = 2;
private boolean mUseFastForward;
private boolean mFromXml;
private boolean mListenersSet;
private View.OnClickListener mNextListener, mPrevListener;
StringBuilder mFormatBuilder;
Formatter mFormatter;
private ImageButton mPauseButton;
private ImageButton mFfwdButton;
private ImageButton mRewButton;
private ImageButton mNextButton;
private ImageButton mPrevButton;
public FMediaController(Context context, AttributeSet attrs) {
super(context, attrs);
mRoot = this;
mContext = context;
mUseFastForward = true;
mFromXml = true;
}
#Override
public void onFinishInflate() {
if (mRoot != null)
initControllerView(mRoot);
}
public FMediaController(Context context, boolean useFastForward) {
super(context);
mContext = context;
mUseFastForward = useFastForward;
initFloatingWindow();
}
public FMediaController(Context context) {
super(context);
mContext = context;
mUseFastForward = true;
initFloatingWindow();
}
private void initFloatingWindow() {
mWindowManager = (WindowManager)mContext.getSystemService("window");
mWindow = PolicyManager.makeNewWindow(mContext);
mWindow.setWindowManager(mWindowManager, null, null);
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
mDecor = mWindow.getDecorView();
mDecor.setOnTouchListener(mTouchListener);
mWindow.setContentView(this);
mWindow.setBackgroundDrawableResource(android.R.color.transparent);
// While the media controller is up, the volume control keys should
// affect the media stream type
mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC);
setFocusable(true);
setFocusableInTouchMode(true);
setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
requestFocus();
}
private OnTouchListener mTouchListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mShowing) {
hide();
}
}
return false;
}
};
public void setMediaPlayer(MediaPlayerControl player) {
mPlayer = player;
updatePausePlay();
}
/**
* Set the view that acts as the anchor for the control view.
* This can for example be a VideoView, or your Activity's main view.
* #param view The view to which to anchor the controller when it is visible.
*/
public void setAnchorView(View view) {
mAnchor = view;
FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT
);
removeAllViews();
View v = makeControllerView();
addView(v, frameParams);
}
/**
* Create the view that holds the widgets that control playback.
* Derived classes can override this to create their own.
* #return The controller view.
* #hide This doesn't work as advertised
*/
protected View makeControllerView() {
LayoutInflater inflate = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mRoot = inflate.inflate(R.layout.media_controller, null);
initControllerView(mRoot);
return mRoot;
}
private void initControllerView(View v) {
mPauseButton = (ImageButton) v.findViewById(R.id.pause);
if (mPauseButton != null) {
mPauseButton.requestFocus();
mPauseButton.setOnClickListener(mPauseListener);
}
mFfwdButton = (ImageButton) v.findViewById(R.id.ffwd);
if (mFfwdButton != null) {
mFfwdButton.setOnClickListener(mFfwdListener);
if (!mFromXml) {
mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE);
}
}
mRewButton = (ImageButton) v.findViewById(R.id.rew);
if (mRewButton != null) {
mRewButton.setOnClickListener(mRewListener);
if (!mFromXml) {
mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE);
}
}
// By default these are hidden. They will be enabled when setPrevNextListeners() is called
mNextButton = (ImageButton) v.findViewById(R.id.next);
if (mNextButton != null && !mFromXml && !mListenersSet) {
mNextButton.setVisibility(View.GONE);
}
mPrevButton = (ImageButton) v.findViewById(R.id.prev);
if (mPrevButton != null && !mFromXml && !mListenersSet) {
mPrevButton.setVisibility(View.GONE);
}
mProgress = (ProgressBar) v.findViewById(R.id.mediacontroller_progress);
if (mProgress != null) {
if (mProgress instanceof SeekBar) {
SeekBar seeker = (SeekBar) mProgress;
seeker.setOnSeekBarChangeListener(mSeekListener);
}
mProgress.setMax(1000);
}
mEndTime = (TextView) v.findViewById(R.id.time);
mCurrentTime = (TextView) v.findViewById(R.id.time_current);
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
installPrevNextListeners();
}
/**
* Show the controller on screen. It will go away
* automatically after 3 seconds of inactivity.
*/
public void show() {
show(sDefaultTimeout);
}
/**
* Show the controller on screen. It will go away
* automatically after 'timeout' milliseconds of inactivity.
* #param timeout The timeout in milliseconds. Use 0 to show
* the controller until hide() is called.
*/
public void show(int timeout) {
if (!mShowing && mAnchor != null) {
setProgress();
int [] anchorpos = new int[2];
mAnchor.getLocationOnScreen(anchorpos);
WindowManager.LayoutParams p = new WindowManager.LayoutParams();
p.gravity = Gravity.TOP;
p.width = mAnchor.getWidth();
p.height = LayoutParams.WRAP_CONTENT;
p.x = 0;
p.y = anchorpos[1] + mAnchor.getHeight() - p.height;
p.format = PixelFormat.TRANSLUCENT;
p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
p.token = null;
p.windowAnimations = 0; // android.R.style.DropDownAnimationDown;
mWindowManager.addView(mDecor, p);
mShowing = true;
}
updatePausePlay();
// cause the progress bar to be updated even if mShowing
// was already true. This happens, for example, if we're
// paused with the progress bar showing the user hits play.
mHandler.sendEmptyMessage(SHOW_PROGRESS);
Message msg = mHandler.obtainMessage(FADE_OUT);
if (timeout != 0) {
mHandler.removeMessages(FADE_OUT);
mHandler.sendMessageDelayed(msg, timeout);
}
}
public boolean isShowing() {
return mShowing;
}
/**
* Remove the controller from the screen.
*/
public void hide() {
if (mAnchor == null)
return;
if (mShowing) {
try {
mHandler.removeMessages(SHOW_PROGRESS);
mWindowManager.removeView(mDecor);
} catch (IllegalArgumentException ex) {
Log.w("MediaController", "already removed");
}
mShowing = false;
}
}
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
int pos;
switch (msg.what) {
case FADE_OUT:
hide();
break;
case SHOW_PROGRESS:
pos = setProgress();
if (!mDragging && mShowing && mPlayer.isPlaying()) {
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000 - (pos % 1000));
}
break;
}
}
};
private String stringForTime(int timeMs) {
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours > 0) {
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
private int setProgress() {
if (mPlayer == null || mDragging) {
return 0;
}
int position = mPlayer.getCurrentPosition();
int duration = mPlayer.getDuration();
if (mProgress != null) {
if (duration > 0) {
// use long to avoid overflow
long pos = 1000L * position / duration;
mProgress.setProgress( (int) pos);
}
int percent = mPlayer.getBufferPercentage();
mProgress.setSecondaryProgress(percent * 10);
}
if (mEndTime != null)
mEndTime.setText(stringForTime(duration));
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime(position));
return position;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
show(sDefaultTimeout);
return true;
}
#Override
public boolean onTrackballEvent(MotionEvent ev) {
show(sDefaultTimeout);
return false;
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
if (event.getRepeatCount() == 0 && event.isLongPress() && (
keyCode == KeyEvent.KEYCODE_HEADSETHOOK ||
keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE ||
keyCode == KeyEvent.KEYCODE_SPACE)) {
doPauseResume();
show(sDefaultTimeout);
return true;
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {
if (mPlayer.isPlaying()) {
mPlayer.pause();
updatePausePlay();
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
// don't show the controls for volume adjustment
return super.dispatchKeyEvent(event);
} else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
hide();
return true;
} else {
show(sDefaultTimeout);
}
return super.dispatchKeyEvent(event);
}
private View.OnClickListener mPauseListener = new View.OnClickListener() {
public void onClick(View v) {
doPauseResume();
show(sDefaultTimeout);
}
};
private void updatePausePlay() {
if (mRoot == null)
return;
ImageButton button = (ImageButton) mRoot.findViewById(R.id.pause);
if (button == null)
return;
if (mPlayer.isPlaying()) {
button.setImageResource(android.R.drawable.ic_media_pause);
} else {
button.setImageResource(android.R.drawable.ic_media_play);
}
}
private void doPauseResume() {
if (mPlayer.isPlaying()) {
mPlayer.pause();
} else {
mPlayer.start();
}
updatePausePlay();
}
private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
long duration;
public void onStartTrackingTouch(SeekBar bar) {
show(3600000);
duration = mPlayer.getDuration();
}
public void onProgressChanged(SeekBar bar, int progress, boolean fromtouch) {
if (fromtouch) {
mDragging = true;
duration = mPlayer.getDuration();
long newposition = (duration * progress) / 1000L;
mPlayer.seekTo( (int) newposition);
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime( (int) newposition));
}
}
public void onStopTrackingTouch(SeekBar bar) {
mDragging = false;
setProgress();
updatePausePlay();
show(sDefaultTimeout);
}
};
#Override
public void setEnabled(boolean enabled) {
if (mPauseButton != null) {
mPauseButton.setEnabled(enabled);
}
if (mFfwdButton != null) {
mFfwdButton.setEnabled(enabled);
}
if (mRewButton != null) {
mRewButton.setEnabled(enabled);
}
if (mNextButton != null) {
mNextButton.setEnabled(enabled && mNextListener != null);
}
if (mPrevButton != null) {
mPrevButton.setEnabled(enabled && mPrevListener != null);
}
if (mProgress != null) {
mProgress.setEnabled(enabled);
}
super.setEnabled(enabled);
}
private View.OnClickListener mRewListener = new View.OnClickListener() {
public void onClick(View v) {
int pos = mPlayer.getCurrentPosition();
pos -= 5000; // milliseconds
mPlayer.seekTo(pos);
setProgress();
show(sDefaultTimeout);
}
};
private View.OnClickListener mFfwdListener = new View.OnClickListener() {
public void onClick(View v) {
int pos = mPlayer.getCurrentPosition();
pos += 15000; // milliseconds
mPlayer.seekTo(pos);
setProgress();
show(sDefaultTimeout);
}
};
private void installPrevNextListeners() {
if (mNextButton != null) {
mNextButton.setOnClickListener(mNextListener);
mNextButton.setEnabled(mNextListener != null);
}
if (mPrevButton != null) {
mPrevButton.setOnClickListener(mPrevListener);
mPrevButton.setEnabled(mPrevListener != null);
}
}
public void setPrevNextListeners(View.OnClickListener next, View.OnClickListener prev) {
mNextListener = next;
mPrevListener = prev;
mListenersSet = true;
if (mRoot != null) {
installPrevNextListeners();
if (mNextButton != null && !mFromXml) {
mNextButton.setVisibility(View.VISIBLE);
}
if (mPrevButton != null && !mFromXml) {
mPrevButton.setVisibility(View.VISIBLE);
}
}
}
public interface MediaPlayerControl {
void start();
void pause();
int getDuration();
int getCurrentPosition();
void seekTo(int pos);
boolean isPlaying();
int getBufferPercentage();
};
}
and I am getting error at "Policy manager" at initfloatwindow method and I have imported import com.android.internal.policy.PolicyManager
private void initFloatingWindow() {
mWindowManager = (WindowManager)mContext.getSystemService("window");
mWindow = PolicyManager.makeNewWindow(mContext);//I got error here
mWindow.setWindowManager(mWindowManager, null, null);
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
mDecor = mWindow.getDecorView();
mDecor.setOnTouchListener(mTouchListener);
mWindow.setContentView(this);
mWindow.setBackgroundDrawableResource(android.R.color.transparent);
// While the media controller is up, the volume control keys should
// affect the media stream type
mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC);
setFocusable(true);
setFocusableInTouchMode(true);
setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
requestFocus();
}
Please anyone can help me please.Thanks in advance
PolicyManager is an internal class, not in puplic API so you cannot use it.