I am creating an application in which i am setting a gallery of images with shuffling effect on wallpaper. shuffling effect is working if app is in background.
But the problem is when i change my wallpaper from my device to set on home screen(not from application but select form wallpapers of device), that wallpaper is setting on my home screen and the shuffling effect remains continue(because i think service is running). Can someone please tell me what is the issue and how to solve this. This is my service class:
public class WallpaperService extends Service {
ArrayList<String> arrayList = new ArrayList<>();
int counter = 0;
Bitmap bmImg = null;
int seconds;
public WallpaperService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flag, int startId) {
super.onStartCommand(intent, flag, startId);
arrayList = intent.getStringArrayListExtra("image_url");
seconds = intent.getIntExtra("seconds", 5000 * 60);
Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show();
SaveWallpaperAsync async = new SaveWallpaperAsync();
async.execute();
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onTaskRemoved(Intent rootIntent){
Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
restartServiceTask.setPackage(getPackageName());
PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
myAlarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartPendingIntent);
}
public class SaveWallpaperAsync extends AsyncTask<String, Integer, Void> {
URL ImageUrl;
Bitmap bmImg = null;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
Toast.makeText(WallpaperService.this, "downloading", Toast.LENGTH_SHORT).show();
}
#Override
protected Void doInBackground(String... args) {
// TODO Auto-generated method stub
InputStream is = null;
for (int i = 0; i < arrayList.size(); i++) {
try {
ImageUrl = new URL(arrayList.get(i));
HttpURLConnection conn = (HttpURLConnection) ImageUrl.openConnection();
conn.setDoInput(true);
conn.connect();
is = conn.getInputStream();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
bmImg = BitmapFactory.decodeStream(is, null, options);
saveImageToInternalStorage(bmImg, i);
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
Toast.makeText(WallpaperService.this, "Downloaded", Toast.LENGTH_SHORT).show();
createNotificationIcon();
}
}
protected String saveImageToInternalStorage(Bitmap bitmap, int index) {
File filepath = Environment.getExternalStorageDirectory();
File dir = new File(filepath.getAbsolutePath()
+ "/Dark Wallpapers/");
if (!dir.exists()){
dir.mkdirs();
}
File file = new File(dir, "UniqueFileName" + index + ".jpg");
try {
OutputStream stream = null;
stream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
stream.flush();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
Uri savedImageURI = Uri.parse(file.getAbsolutePath());
return savedImageURI.toString();
}
private Bitmap loadImageFromStorage(int counter) {
Bitmap b = null;
try {
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Dark Wallpapers/", "UniqueFileName" + counter + ".jpg");
b = BitmapFactory.decodeStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return b;
}
public void createNotificationIcon() {
final WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
counter += 1;
if (counter < arrayList.size()) {
try {
wallpaperManager.setBitmap(loadImageFromStorage(counter));
wallpaperManager.suggestDesiredDimensions(1080, 1920);
} catch (IOException e) {
e.printStackTrace();
}
} else if (counter == arrayList.size()) {
counter = 0;
try {
wallpaperManager.setBitmap(loadImageFromStorage(counter));
wallpaperManager.suggestDesiredDimensions(1080, 1920);
} catch (IOException e) {
e.printStackTrace();
}
}
}
},
0,
seconds);
}}
This is how i called it from activity:
Intent intent = new Intent(CategoryActivity.this, WallpaperService.class);
intent.putExtra("image_url", img_urls);
intent.putExtra("seconds", 60);
intent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startService(intent);
If I have understood well you would like to get an "event" (or just to know...) when the home wallpaper is changed. Is it right?
Maybe you would like to stop your Service if it detects that the User wants to set a fixed wallpaper from that moment.
There isn't any Event to do this, but there is a solution: remember which wallpaper you have automatically changed from the App (maybe memorize the path+filename in a file in your /xxxxx/files folder) and then check the Current Wallpaper just before trying to set the new one, using this:
WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
Drawable wallpaperDrawable = wallpaperManager.getDrawable();
In this way if the Current Wallpaper is the same of your last and memorized filename than there is a 99% of chance that the user doesn't set a fixed one by his/her own. (the remaining 1% could be the possibility that the user manually sets the SAME wallpaper you automatically set as the last one, but it's very-very rare)
Related
I have the following method for the button onclick listener
titleBar.setRightBtnOnclickListener(v -> {
savePicture();
PublishActivity.openWithPhotoUri(this, Uri.fromFile(photoPath));
});
i want to be able to pass the filepath of the photo to another activity
here i am saving the bitmap
private void savePicture(){
//加滤镜
final Bitmap newBitmap = Bitmap.createBitmap(mImageView.getWidth(), mImageView.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas cv = new Canvas(newBitmap);
RectF dst = new RectF(0, 0, mImageView.getWidth(), mImageView.getHeight());
try {
cv.drawBitmap(mGPUImageView.capture(), null, dst, null);
} catch (InterruptedException e) {
e.printStackTrace();
cv.drawBitmap(currentBitmap, null, dst, null);
}
//加贴纸水印
EffectUtil.applyOnSave(cv, mImageView);
new SavePicToFileTask().execute(newBitmap);
}
Then here am using the async
public class SavePicToFileTask extends AsyncTask<Bitmap,Void,String>{
Bitmap bitmap;
#Override
protected void onPreExecute() {
super.onPreExecute();
showProgressDialog("图片处理中...");
}
#Override
protected String doInBackground(Bitmap... params) {
String fileName = null;
try {
bitmap = params[0];
String picName = TimeUtils.dtFormat(new Date(), "yyyyMMddHHmmss");
fileName = ImageUtils.saveToFile(FileUtils.getInst().getPhotoSavedPath() + "/"+ picName, false, bitmap);
photoPath = new File(fileName);
} catch (Exception e) {
e.printStackTrace();
toast("图片处理错误,请退出相机并重试", Toast.LENGTH_LONG);
}
return fileName;
}
#Override
protected void onPostExecute(String fileName) {
super.onPostExecute(fileName);
dismissProgressDialog();
if (StringUtils.isEmpty(fileName)) {
return;
}
}
}
so am having trouble on how to get the photo path and then using Uri pass it to the next activity
thanks guys
You should pass the filename as a String using an Intent.
Intent intent = new Intent(getBaseContext(), NEWACTIVITYNAME.class);
intent.putExtra("FILE_NAME", fileName);
startActivity(intent);
Then you can access that intent on next activity:
String fileName = getIntent().getStringExtra("fileName");
I want to save imageView into sd card but I get the following exception (some times not always) when I try to get bitmap from imageView. Can somebody please help me? Thanks in advance
Caused by: java.lang.IllegalArgumentException: width and height must be > 0 at android.graphics.Bitmap.createBitmap(Bitmap.java:922)
public static class SaveImageToSD extends AsyncTask<String, Void, String> {
Context context;
ImageView mImageView;
ProgressDialog progressDialog;
public SaveImageToSD(Context context, ImageView iv, String name) {
this.context = context;
this.mImageView = iv;
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(context, "", context.getResources().getString(R.string.please_wait), true);
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected String doInBackground(String... x) {
File projectFolder = new File(Environment.getExternalStorageDirectory() + File.separator + Settings.projectFolder + File.separator);
boolean folderCreateSuccess = true;
if (!projectFolder.exists()) {
folderCreateSuccess = projectFolder.mkdir();
}
if (folderCreateSuccess) {
Bitmap bitmap;
// Exception in if statement
if (mImageView.getDrawable() instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) mImageView.getDrawable()).getBitmap();
} else {
Drawable d = mImageView.getDrawable();
bitmap = Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
d.draw(canvas);
}
File image = new File(projectFolder, "GE_" + System.currentTimeMillis() + ".jpg");
boolean success = false;
// Encode the file as a PNG image.
FileOutputStream outStream;
try {
outStream = new FileOutputStream(image);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
/* 100 to keep full quality of the image */
outStream.flush();
outStream.close();
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "title");
values.put(MediaStore.Images.Media.DESCRIPTION, "description");
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.ImageColumns.BUCKET_ID, image.toString().toLowerCase(Locale.US).hashCode());
values.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, image.getName().toLowerCase(Locale.US));
values.put("_data", image.getAbsolutePath());
ContentResolver cr = context.getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
success = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
progressDialog.dismiss();
if (success) {
((ActionBarActivity)context).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(context, context.getResources().getString(R.string.image_successfully_saved), Toast.LENGTH_SHORT).show();
}
});
} else {
((ActionBarActivity)context).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(context, context.getResources().getString(R.string.image_successfully_saved), Toast.LENGTH_SHORT).show();
}
});
}
} else {
Log.i("Create Folder", "Error during create folder");
}
return "";
}
}
to set image I use following code, I'm using transparentDrawable because of Picasso wrap content problem
transparentDrawable.setBounds(new Rect(0, 0, 1000, 1000));
Picasso.with(mContext).load(((FBPhotoCard) mImageCards.get(position)).getThumbnail()).placeholder(transparentDrawable).noFade().into(holder.imageView);
I think the exception is of because d.getIntrinsicWidth(), d.getIntrinsicHeight() at line bitmap = Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
According to Android docs drawable.getIntrinsicWidth() Return the intrinsic width of the underlying drawable object. Returns -1 if it has no intrinsic width, such as with a solid color. So make sure to pass values greater than 1 to Bitmap.createBitmap() method
This error you are getting because d.getIntrinsicWidth(), d.getIntrinsicHeight() returning 0 try to put some constant value and then check like 100.
I am trying to do a code in an asynctask that takes a picture from the camera and send it to a server over UDP 100 times. However, the PictureCallback isn't called. Can someone please help me?
this is what i tried:
public class MainAsyncTask extends AsyncTask<Void, String, Void> {
protected static final String TAG = null;
public MainActivity mainAct;
public MainAsyncTask(MainActivity mainActivity)
{
super();
this.mainAct = mainActivity;
}
#Override
protected Void doInBackground(Void... params) {
DatagramSocket clientSocket = null;
InetAddress IPAddress = null;
try {
clientSocket = new DatagramSocket();
IPAddress = InetAddress.getByName("192.168.1.15");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte [] data;
DatagramPacket sendPacket;
try {
for (int i=0; i < 100; i++)
{
publishProgress("");
File file = new File(Environment.getExternalStorageDirectory()+ File.separator +"img.jpg");
while (!file.exists() || file.length() == 0);
Bitmap screen = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+ File.separator +"img.jpg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
screen.compress(Bitmap.CompressFormat.JPEG, 15, bytes);
data = bytes.toByteArray();
sendPacket = new DatagramPacket(data, data.length, IPAddress, 3107);
clientSocket.send(sendPacket);
file.delete();
}
clientSocket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
publishProgress(e.getMessage());
}
return null;
}
public static void takeSnapShots(MainActivity mainAct)
{
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera)
{
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(Environment.getExternalStorageDirectory()+File.separator+"img"+".jpg");
outStream.write(data);
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally
{
camera.stopPreview();
camera.release();
camera = null;
}
Log.d(TAG, "onPictureTaken - jpeg");
}
};
SurfaceView surface = new SurfaceView(mainAct.getApplicationContext());
Camera camera = Camera.open();
try {
camera.setPreviewDisplay(surface.getHolder());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
camera.takePicture(null,null,jpegCallback);
}
protected void onProgressUpdate(String... progress) {
takeSnapShots(mainAct);
}
#Override
protected void onPostExecute(Void result)
{
}
}
I don't think that AsyncTask is the most convenient tool to do the job.
You need a SurfaceView that is not simply created out of nowhere, but connected to the screen. You should initialize your camera only once, and you cannot call camera.takePicture() in a loop. You can call takePicture() from onPictureTaken() callback, but you should also remember that you cannot work with sockets from the UI thread. Luckily, you can follow the Google recommendations.
the recommended way to access the camera is to open Camera on a separate thread.
and
Callbacks will be invoked on the event thread open(int) was called from.
If you open camera in a new HandlerThread, as shown here, the picture callbacks will arrive on that beckground thread, which may be used also for networking.
Also, I recommend you to send directly the JPEG buffer that you receive from the camera. I believe that overhead of saving image to file, reading the file to bitmap, and compressing the latter to another JPEG may be way too much. To control the image size, choose appropriate picture size. Note that the size should be selected from the list of sizes supported by the specific camera.
public class CameraView extends SurfaceView
implements SurfaceHolder.Callback, Camera.PictureCallback {
private static final String TAG = "CameraView";
private Camera camera;
private HandlerThread cameraThread;
private Handler handler;
private boolean bCameraInitialized = false;
private int picturesToTake = 0;
public CameraView(Context context, AttributeSet attr) {
super(context, attr);
// install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
getHolder().addCallback(this);
}
#Override public void surfaceCreated(SurfaceHolder holder) {
cameraThread = new HandlerThread("CameraHandlerThread");
cameraThread.start();
handler = new Handler(cameraThread.getLooper());
hanlder.post(new Runnable() {
#Override public void run() {
openRearCamera();
bCameraInitialized = false;
}
});
}
#Override public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
Log.d(TAG, "Camera release");
camera.release();
camera = null;
bCameraInitialized = false;
}
}
// finalize the camera init now that we know preview size
#Override public void surfaceChanged(SurfaceHolder holder, int format, final int w, final int h) {
Log.w(TAG, "surfaceChanged(" + w + ", " + h + ")");
if (!bCameraInitialized) {
cameraSetup(w, h);
bCameraInitialized = true;
}
}
private void openRearCamera() {
if (camera != null) {
Log.e(TAG, "openRearCamera(): camera is not null");
return;
}
try {
camera = Camera.open(0);
Log.d(TAG, "Camera ready " + String.valueOf(camera));
}
catch (Throwable e) {
Log.e(TAG, "openRearCamera(): Camera.open() failed", e);
}
}
private void cameraSetup(int w, int h) {
if (camera == null) {
Log.e(TAG, "cameraSetup(): camera is null");
return;
}
Log.d(TAG, "Camera setup");
try {
Camera.Parameters params = camera.getParameters();
// still picture settings - be close to preview size
Camera.Size pictureSize = params.getSupportedPictureSizes()[0];
params.setPictureSize(pictureSize.width, optimalPictureSize.height);
camera.setParameters(params);
camera.setPreviewDisplay(getHolder());
camera.startPreview();
}
catch (Throwable e) {
Log.e(TAG, "Failed to finalize camera setup", e);
}
}
private void sendJpeg(byte[] data) {
DatagramSocket clientSocket = null;
InetAddress IPAddress = null;
try {
clientSocket = new DatagramSocket();
IPAddress = InetAddress.getByName("192.168.1.15");
}
catch (Exception e) {
Log.e(TAG, "failed to initialize client socket", e);
}
DatagramPacket sendPacket;
sendPacket = new DatagramPacket(data, data.length, IPAddress, 3107);
clientSocket.send(sendPacket);
Log.d(TAG, "sent image");
}
#Override public void onPictureTaken(byte[] data, Camera camera) {
sendJpeg(data);
camera.startPreview();
takePictures(picturesToTake-1);
}
public void takePictures(int n) {
if (n > 0) {
picturesToTake = n;
Log.d(TAG, "take " + n + " images");
camera.takePicture(null, null, this);
}
else {
Log.d(TAG, "all images captured");
}
}
}
The class above is a compilation from several projects, with error checking reduced to minimum for brevity. It may require some fixes to compile. You simply add a <CameraView /> to your activity layout, and call its takePictures when the user clicks a button or something.
Do you call to your AsyncTask like this? Just to create the AsyncTask is not enouge.
new MainAsyncTask(ActivityContext).execute();
You can't do this
camera.setPreviewDisplay(surface.getHolder());
From the docs:
http://developer.android.com/reference/android/hardware/Camera.html#setPreviewDisplay(android.view.SurfaceHolder)
"The SurfaceHolder must already contain a surface when this method is called. If you are using SurfaceView, you will need to register a SurfaceHolder.Callback with addCallback(SurfaceHolder.Callback) and wait for surfaceCreated(SurfaceHolder) before calling setPreviewDisplay() or starting preview."
You'd have to do something like this:
SurfaceHolder surfaceHolder = surface.getHolder();
surfaceHolder.addCallback(new Callback() {
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
camera.takePicture(null,null,jpegCallback);
} catch (IOException e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {}
}
);
I'm using Apache's FTPClient to upload files to my server (images from the gallery if it matters)
I'm having a small and pretty insignificant problem, but I would still like to solve it.
The problem is that the bar is filled and reaches 100% before the upload actually completes, causing the dialog to show 100% for an extra 2-3 seconds on small files (and could be a lot more on files weighing several MBs).
I'm guessing it's because of the conversion from long to int, but that's just a guess.
Here's the code:
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(UploadActivity.this);
dialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
uploadImage.cancel(true);
}
});
dialog.setMessage("Uploading...\nPlease Wait.");
dialog.setIndeterminate(false);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress(0);
dialog.setCancelable(false);
dialog.setMax((int)(file.length()/1024));
dialog.setProgressNumberFormat ("%1dKB/%2dKB");
dialog.show();
}
#Override
protected String doInBackground(Void... params) {
CopyStreamAdapter streamListener = new CopyStreamAdapter() {
#Override // THIS PART IS RESPONSIBLE FOR UPDATING THE PROGRESS
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
int percent = (int) (totalBytesTransferred * 100 / file.length());
publishProgress(percent);
}
};
String name = null;
ftp.setCopyStreamListener(streamListener);
FileInputStream fis = null;
try {
String extension = "";
String fileName = file.getName();
int i = fileName.lastIndexOf('.');
int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
if (i > p) {
extension = fileName.substring(i + 1);
}
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyy-hhmmss-SSS");
name = String.format("File-%s.%s", sdf.format(new Date()), extension);
ftp.connect(FTP_SERVER);
ftp.enterLocalPassiveMode();
ftp.login(ftpUser, ftpPassword);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
fis = new FileInputStream(file);
if (!ftp.storeFile(name, fis)) {
showToast("Failed uploading");
return null;
}
ftp.logout();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return name;
}
#Override
protected void onProgressUpdate(Integer... values) {
dialog.setProgress(values[0]);
}
Thanks!
I've written a camera application, but when I want to show the camera's live preview(before taking the picture), the preview is rotated 90 degrees! here is my camera activity's code :
public class CameraActivity extends Activity{
public static final int MEDIA_TYPE_IMAGE = 1 ;
private Camera mCamera;
private CameraPreview mPreview;
Uri photoPath ;
protected void onStop()
{
super.onStop();
mCamera.release();
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
ViewGroup.LayoutParams previewParam = preview.getLayoutParams() ;
Parameters cameraParam = mCamera.getParameters() ;
double ratio = (double)cameraParam.getPictureSize().height / (double)cameraParam.getPictureSize().width ;
// previewParam.height= cameraParam.getPictureSize().height / 5 ;
// previewParam.width = cameraParam.getPictureSize().width / 5 ;
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
try
{
display.getSize(size);
}
catch(java.lang.NoSuchMethodError ignore)
{
size.x = display.getWidth();
size.y = display.getHeight() ;
}
int width = size.x;
int height = size.y;
previewParam.width = width;
previewParam.height = (int)(previewParam.width * ratio) ;
// preview.setLayoutParams(previewParam) ;
preview.addView(mPreview);
}
//Camera Classes here
private final static String TAG = "Navid";
public static Camera getCameraInstance()
{
Camera c = null ;
try
{
c = Camera.open() ;
}
catch(Exception e)
{
}
return c ;
}
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder mHolder ;
private Camera mCamera;
public CameraPreview(Context context , Camera camera)
{
super(context) ;
mCamera = camera ;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder)
{
try
{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch(IOException e)
{
Log.d(TAG,"Camera Preview Failed!: "+e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder , int m , int n , int w)
{
}
public void surfaceDestroyed(SurfaceHolder holder)
{
}
}
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
}else {
return null;
}
return mediaFile;
}
//save the picture here
private PictureCallback mPicture = new PictureCallback() {
// public final static int MEDIA_TYPE_IMAGE = 1 ;
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
photoPath = Uri.fromFile(pictureFile);
if (pictureFile == null){
Log.d("Errore Doorbin", "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
// these lines are for the gallery to scan the SDCard manually
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ mediaStorageDir)));
// photoPath = Uri.fromFile(mediaStorageDir) ;
/* MediaScannerConnection.scanFile(CameraActivity.this,
new String[] { fos.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
// code to execute when scanning is complete
}
});*/
// fos.close();
} catch (FileNotFoundException e) {
Log.d("Errore Doorbin", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Errore Doorbin", "Error accessing file: " + e.getMessage());
}
catch (Exception e)
{
Log.d("Errore Doorbin", "errore Kolli dade!" + e.getMessage()) ;
}
}
};
public void capture(View v)
{
//mCamera.takePicture(null, null, mPicture);
//mCamera.release();
//mCamera = getCameraInstance() ;
//mCamera.startPreview();
TakePictureTask takePicture = new TakePictureTask() ;
takePicture.execute() ;
}
public void accept(View v)
{
Intent data = new Intent() ;
data.setData(photoPath) ;
setResult(RESULT_OK, data);
finish() ;
}
public void retake(View v)
{
Button button = (Button)findViewById(R.id.button_accept);
button.setVisibility(View.GONE);
button = (Button)findViewById(R.id.button_capture) ;
button.setVisibility(View.VISIBLE) ;
button = (Button)findViewById(R.id.button_retake);
button.setVisibility(View.GONE) ;
mCamera.startPreview();
}
/**
* A pretty basic example of an AsyncTask that takes the photo and
* then sleeps for a defined period of time before finishing. Upon
* finishing, it will restart the preview - Camera.startPreview().
*/
private class TakePictureTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPostExecute(Void result) {
// This returns the preview back to the live camera feed
Button button = (Button)findViewById(R.id.button_accept) ;
button.setVisibility(View.VISIBLE) ;
button = (Button)findViewById(R.id.button_retake) ;
button.setVisibility(View.VISIBLE);
button = (Button)findViewById(R.id.button_capture);
button.setVisibility(View.GONE);
//mCamera.startPreview();
}
#Override
protected Void doInBackground(Void... params) {
mCamera.takePicture(null, null, mPicture);
// Sleep for however long, you could store this in a variable and
// have it updated by a menu item which the user selects.
try {
Thread.sleep(3000); // 3 second preview
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
and in my application's manifest I've changed this activities orientation to portrait!
What is the problem ? why does it look like this ?
This happens to be a bug in earlier versions of Android.
A workaround is to rotate the camera by default.
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
camera.setDisplayOrientation(90);
lp.height = previewSurfaceHeight;
lp.width = (int) (previewSurfaceHeight / aspect);
} else {
camera.setDisplayOrientation(0);
lp.width = previewSurfaceWidth;
lp.height = (int) (previewSurfaceWidth / aspect);
}