Android 2.2 SDK - Droid X Camera Activity doesn't finish properly - java

I noticed the default camera activity I call on a Droid X is different looking than the one on my Droid and Nexus One. After selecting "OK" on the Droid and Nexus One, the activity would finish - the Droid X has a "Done" button (which takes you back to the Camera, instead of finishing the activity), and the only way to get to the screen I want is to hit the "Back" button.
Here is the class that works on Android 2.2/2.3, but not for Droid X's:
package com.android.xxx;
import java.io.File;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.Window;
public class CameraView extends MenusHolder {
protected String _path;
protected boolean _taken;
protected static final String PHOTO_TAKEN = "photo_taken";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.create_event_view);
/*
* save to sd
*/
File imageDirectory = new File(
Environment.getExternalStorageDirectory() + "/MyPath/");
imageDirectory.mkdirs();
/*
* temp image overwrites each time for space
*/
_path = Environment.getExternalStorageDirectory()
+ "/MyPath/temporary_image.jpg";
startCameraActivity();
}
protected void startCameraActivity() {
File file = new File(_path);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (resultCode) {
case 0:
setResult(5);
finish();
break;
case -1:
onPhotoTaken();
break;
}
}
protected void onPhotoTaken() {
_taken = true;
setResult(0);
finish();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(CameraView.PHOTO_TAKEN, _taken);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.getBoolean(CameraView.PHOTO_TAKEN)) {
onPhotoTaken();
}
}
}

I solved this with a really really ugly workaround. I coded two functions to read and write files from sdcard (taken from here: http://www.sgoliver.net/blog/?p=2035).
private boolean readFile() {
try
{
File sd_path = Environment.getExternalStorageDirectory();
File f = new File(sd_path.getAbsolutePath(), "lock_camera_oncreate");
BufferedReader fin =
new BufferedReader(
new InputStreamReader(
new FileInputStream(f)));
String text = fin.readLine();
fin.close();
Log.e("Files", "Reading file");
return true;
}
catch (Exception ex)
{
Log.e("Files", "Error reading file from SD Card");
return false;
}
}
private void createFile() {
try
{
File sd_path = Environment.getExternalStorageDirectory();
File f = new File(sd_path.getAbsolutePath(), "lock_camera_oncreate");
OutputStreamWriter fout =
new OutputStreamWriter(
new FileOutputStream(f));
fout.write("Semaphore test.");
fout.close();
Log.e("Files", "File writed");
}
catch (Exception ex)
{
Log.e("Files", "Error reading file from SD Card");
}
}
Then, in onCreate function, I make this:
public void onCreate(Bundle savedInstanceState) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
super.onCreate(savedInstanceState);
if(readFile() == true)
{
File sd_path = Environment.getExternalStorageDirectory();
File f = new File(sd_path.getAbsolutePath(), "lock_camera_oncreate");
f.delete();
Intent intent = this.getIntent();
this.setResult(RESULT_OK, intent);
return;
}
createFile();
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCurrentImagePath)));
startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
}
The setRequestedOrientation call solves the issue when you are using your app in portrait mode, but when camera is launched, you put the mobile in landscape and then shoot the photo.
Then, the ugly readFile thing checks if a lock_camera_oncreate file exists and if it's true,
then an additional onCreate call happened, so delete file and RETURN from this activity.
If activity advances, means the file's not created and there is only one camera activity running.
Hope it helps, it's ugly but worked for me :D

Dude... it's just a bug. I had the same problem and there's no way to workaround that. It sometimes work, and sometimes it does not. I asked the Motorola's guy for help and they said that there's no support for those Android images.

Related

How to share a Video from one app to another app?

Hi guys I am totally new in android app development and need some helped. Actually I am working on project i.e. WhatsApp Status Saver.
I did some basic coding.
But Now I want to share video from VideoView.
I done the code for sending Images.
I used the following code.
public class Picture extends AppCompatActivity {
ImageView mparticularimage,
share;
BitmapDrawable drawable;
Bitmap bitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_picture);
getSupportActionBar().setTitle("Picture");
mparticularimage=findViewById(R.id.particularImage);
share=findViewById(R.id.share);
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//shareoption coding
shareImage();
}
});
private void shareImage() {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
drawable = (BitmapDrawable) mparticularimage.getDrawable();
bitmap = drawable.getBitmap();
File file = new File(getExternalCacheDir()+"/"+"Status downloaded by - Status saver"+".png");
Intent intent;
try {
FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,100, outputStream);
outputStream.flush();
outputStream.close();
intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/+");
intent.putExtra(intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}catch (Exception e){
throw new RuntimeException(e);
}
startActivity(Intent.createChooser(intent,"Share this image via: "));
}
}
The above code perfectly work for Images now how to do the same thing in terms of VideoView and .mp4 files.

Android app in java crashes when trying to open a text file

I am trying to make a simple text editor for Android in Java. I run into a problem, when tring to open a file.
In this line of my code
File file = new File(getExternalFilesDir(filepath), filename);
I got a null pointer exception:
java.lang.NullPointerException: name == null
at java.io.File.<init>(File.java:150)
at java.io.File.<init>(File.java:124)
at my.app.texteditor.MainActivity$1.onClick(MainActivity.java:31)
and my app crashes, leaving the filepicker on my android device open.
For me (after some time of trying to debug my code) it seems that the
protected void onActivityResult(int requestCode, int resultCode, Intent data)
function is never called and thus the filepath and filename are never assigned, which generates the exception. Hovever I am not sure whether I detected the problem correctly and I dont know how to fix it.
Here is the (full) code of my main activity - the one where I am trying to open a file:
package my.app.texteditor;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
public class MainActivity extends AppCompatActivity {
String filepath, filename, folder;
private static final int PICKFILE_RESULT_CODE = 1;
private static int PICKER_RESULT = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button OpenButton = (Button) findViewById(R.id.OpenButton);
OpenButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent getContent = new Intent(Intent.ACTION_GET_CONTENT);
getContent.setType("text/*");
startActivityForResult(getContent, PICKFILE_RESULT_CODE);
File file = new File(getExternalFilesDir(filepath), filename);
Intent openIntent = new Intent(MainActivity.this, ShowFile.class);
openIntent.putExtra("my.app.file", file);
startActivity(openIntent);
}
});
Button NewButton = (Button) findViewById(R.id.NewButton);
NewButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent newIntent = new Intent(MainActivity.this, ShowFile.class);
startActivity(newIntent);
}
});
if (!StorageHandler.isExternalStorageAvailable() || StorageHandler.isExternalStorageReadOnly()) {
OpenButton.setEnabled(false);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
PICKER_RESULT = resultCode;
if (requestCode == PICKFILE_RESULT_CODE) {
if (resultCode == RESULT_OK) {
filepath = data.getData().getPath();
filename = data.getData().getLastPathSegment();
int lastPos = filepath.length() - filename.length();
folder = filepath.substring(0, lastPos);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
When I put this part of my code:
File file = new File(getExternalFilesDir(filepath), filename);
Intent openIntent = new Intent(MainActivity.this, ShowFile.class);
openIntent.putExtra("my.app.file", file);
startActivity(openIntent);
in an if statement, so it will be executed only if the PICKER_RESULT variable is changed in onActivityResult function - like this:
if(PICKER_RESULT!=-1) {
File file = new File(getExternalFilesDir(filepath), filename);
Intent openIntent = new Intent(MainActivity.this, ShowFile.class);
openIntent.putExtra("my.app.file", file);
startActivity(openIntent);
}
then my android device opens the filepicker, app DOES NOT crash, but I am not able to open a file - the PICKER_RESULT is still set to -1.
So my quesion is, why is the onActivityResult function never called?
You're trying to use the result of the activity in the onClick event handler. This won't work because the activity is started asynchronously. The event handler will keep running until the end, and only then the activity starts.
All of the code that depends on the activity result should be in
onActivityResult (or a method that's called from it)
startActivityForResult(getContent, PICKFILE_RESULT_CODE);
// MOVE THIS TO onActivityResult
File file = new File(getExternalFilesDir(filepath), filename);
Intent openIntent = new Intent(MainActivity.this, ShowFile.class);
openIntent.putExtra("my.app.file", file);
startActivity(openIntent);

Take a picture without opening the Camera application

I currently have an application with a button that takes a photo. However, when I click the button the default camera application opens, then you manually have to take a photo. How do I get the camera application to not open and just take a picture automatically and save it just by pressing the button in my application? I would like to press the button that I created and it takes a photo and saves it automatically.
MainActivity.java
public class MainActivity extends AppCompatActivity {
//for taking photos
static final int REQUEST_IMAGE_CAPTURE = 1;
String currentPhotoPath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onResume(){
super.onResume();
}
//button to start image capturing process
public void startImageCapture(View view){
dispatchTakePictureIntent();
galleryAddPic();
}
//method for taking a photo
public void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Ensure that there is a camera activity to handle the intent
if(takePictureIntent.resolveActivity(getPackageManager()) != null){
//create the file where the photo should go
File photoFile = null;
try{
photoFile = createImageFile();
}catch(IOException e){
Log.i("ERROR","Error in trying to create file for image");
}
//continue only if the file was successfully created
if (photoFile != null){
Uri photoURI = FileProvider.getUriForFile(this,"com.example.MyProject.provider",photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoURI);
startActivityForResult(takePictureIntent,REQUEST_IMAGE_CAPTURE);
}
}
}
private File createImageFile() throws IOException{
//Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, //prefix
".jpg", //suffix
storageDir //directory
);
//Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
private void galleryAddPic(){
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
}
For me the easiest solution is using camera view (your own wrapper of Camera2 API or existing CameraView) inside your application and making it invisible or placing some view above it, if you want to hide it.
CameraView API is simple (CameraView Getting Started): just add view into layout, set LifecycleOwner, set callback on taking picture and call camera.takePicture(), when you need to take picture.

I know how to make a button open the camera, but I don't how to change the location of the photos that are taken, how can I do this?

I have a button for my camera, but I can't figure out how to make the pictures taken get stored somewhere else. Can you help? My code that I've already got for this button:
<Button style="#style/ButtonsAtHome" android:onClick="cameraButton"
android:textColor="#4CAF50" android:text="CAMERA" />
Java:
public void cameraButton(View view) {
Intent openCamera = new
Intent("android.media.action.IMAGE_CAPTURE");
startActivity(openCamera);
getWindow().setBackgroundDrawable(null);
}
This button opens the camera, but it saves in a default directory, but I don't want it to save there, how can I change the directory, or make the image show up after I take it, so I can edit it. (My app is a photo-editor)
You can use below code to take picture and then store in your app directory:
Open the camera
public void openCamera(View view){
Intent openCamera = new
Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(openCamera,1);
getWindow().setBackgroundDrawable(null);
}
Get the result in onActivityResult() // modify it according to your own need
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 1:
Bitmap photo = (Bitmap) data.getExtras().get("data");
createDirectoryAndSaveFile(photo,"fileName");
}
}
Save image in specified folder
private void saveImageToFolder(Bitmap image, String fileName) {
File directoryName = new File(Environment.getExternalStorageDirectory() + "/MyAppDirectory");
if (!directoryName.exists()) {
directoryName.mkdir();
}
File file = new File(new File("/sdcard/MyAppDirectory/"), fileName + ".JPEG");
if (file.exists()) {
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Add necessary permission :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>

Android mediaplayer won't load Uri with path /documents/audio:1159

I'm trying to play audio files with the built in mediaplayer in Android Studio. I'm using the code below to call an intent and open a third party file manager to get a files Uri and from that the file path whoich I store somewhere. Anyway, if I use a file manager like ES File Explorer I get a path that looks like "/sdcard/some directory/test.mp3" however, if I use the built in file explorer I get a path like "/documents/audio:1159" for the same file. I understand that the latter is an "asset" but when I try to feed this into mediaplayer I get an exception. What am I doing wrong?
The code below shows the intent method I'm using to get the filepath and the code below that shows how I use that file path to get a Uri and feed this into mediaplayer. Just to be clear file paths like "/sdcard/some directory/test.mp3" work fine. File paths like "/documents/audio:1159" don't.
final View.OnClickListener mGlobal_OnClickListener = new View.OnClickListener() {
public void onClick(final View v) {
int resID2 = v.getId();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("audio/*");
try {
startActivityForResult(intent,resID2); }
catch (Exception e) {
Toast.makeText(getApplicationContext(), "Please install a file manager",Toast.LENGTH_LONG).show();
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent result) {
if (resultCode == RESULT_OK)
{
Uri data = result.getData();
String thePath = data.getPath();
// Do something with the file path
}
}
Code used to start mediaplayer based on the file path retrieved from above
Uri myUri = Uri.parse(filePath);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException e) {}
I guess you cannot use Uri like
/documents/audio:1159
when uses Intent MediaPlayer
EDITTED:
Try this code for getting filepath from assets folder
AssetManager am = getAssets();
InputStream inputStream = am.open(file:///android_asset/myfoldername/myfilename);
File file = createFileFromInputStream(inputStream);
private File createFileFromInputStream(InputStream inputStream) {
try{
File f = new File(my_file_name);
OutputStream outputStream = new FileOutputStream(f);
byte buffer[] = new byte[1024];
int length = 0;
while((length=inputStream.read(buffer)) > 0) {
outputStream.write(buffer,0,length);
}
outputStream.close();
inputStream.close();
return f;
}catch (IOException e) {
//Logging exception
}
return null;
}

Categories