Droid RAZR M Camera Freezes when invoked via ACTION_IMAGE_CAPTURE Intent - android

I'm having trouble invoking the built-in camera app on my Droid Razr M using an ACTION_IMAGE_CAPTURE Intent on ICS and was hoping someone else has seen this and knows how to solve/work-around the issue.
My app launches the Camera, waits for the user to capture and accept the image, then processes it upon return. But note that there is NO processing of the image in the sample app, below, and the problem still happens. The key element here is that we immediately re-invoke the camera upon the return from the Intent, to allow the user to continue taking pictures, one after another. This has been working fine on many devices (more than a dozen different devices) but fails on the Droid Razr M running 4.1.2 (as well as earlier versions of ICS). The failure manifests after taking the second photo -- all of the buttons on the camera become disabled and only the back button works. The problem does not happen if we put in a delay of 5 or more seconds in our app before relaunching the Intent -- but that is unacceptable.
Here's a simple repro app that demonstrates the problem (note that you will need to enable the WRITE_EXTERNAL_STORAGE permission for this to work):
public class MainActivity extends Activity {
private static final int RESPONSE_SINGLE_SHOT = 45;
private static final String TAG = "CameraTest";
private String mCameraFilePath = null;
#Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
onLaunchCamera( true ); //The launch is here only for simplification - it also fails in onStart()
}
#Override
protected void onActivityResult( final int requestCode, final int resultCode, final Intent intent )
{
super.onActivityResult(requestCode, resultCode, intent);
processImage( requestCode, resultCode, intent );
}
public void onLaunchCamera( boolean fromUserAction )
{
final String storageState = Environment.getExternalStorageState();
if (storageState.equals(Environment.MEDIA_MOUNTED))
{
final Intent cameraIntent = new Intent( MediaStore.ACTION_IMAGE_CAPTURE );
cameraIntent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET );
final List<ResolveInfo> list = getPackageManager().queryIntentActivities( cameraIntent, 0 );
//Grab the first camera in the list, this should be the camera app that came with the device:
final String packageName = list.get(0).activityInfo.packageName;
final String name = list.get(0).activityInfo.name;
final File publicDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DCIM );
final Time t = new Time();
t.setToNow();
File cameraFile = new File( publicDir, "/Camera/" + makePhotoFileName( t ) );
mCameraFilePath = cameraFile.getAbsolutePath();
Log.i( TAG, "creating camera file: " + mCameraFilePath );
try
{
if ( cameraFile.exists() == false )
{
cameraFile.getParentFile().mkdirs();
if ( cameraFile.createNewFile() )
{
cameraIntent.putExtra( MediaStore.EXTRA_OUTPUT, Uri.fromFile( cameraFile ) );
} else {
Log.e( TAG, "failed to create file:" + cameraFile.getAbsolutePath() );
return;
}
}
} catch ( IOException e )
{
Log.e( TAG, "Could not create file.", e );
return;
}
cameraIntent.setComponent( new ComponentName( packageName, name ) );
startActivityForResult( cameraIntent, RESPONSE_SINGLE_SHOT );
} else {
Log.e(TAG, "SD card not present");
}
}
private void processImage( final int requestCode, final int resultCode, final Intent intent ) {
switch (requestCode)
{
case RESPONSE_SINGLE_SHOT:
if ( resultCode == RESULT_OK )
{
runOnUiThread( new Runnable() {
#Override
public void run() {
onLaunchCamera( false ); //Immediately re-run camera
}
});
}
else {
// delete the placeholder file we created
if ( mCameraFilePath != null ) {
final File cameraFile = new File( mCameraFilePath );
cameraFile.delete();
mCameraFilePath = null;
}
}
break;
default:
break;
}
}
private String makePhotoFileName( final Time t ) {
final String fileName = t.format("IMG_%Y%m%d_%H%M%S") + ".jpg";
return fileName;
}
}
Any help is greatly appreciated.

The only solution that we've been able to come up with for the default camera on the Razr M is to not immediately return to the camera after capturing an image. We did this by inserting the following code just before the try-catch block in onLaunchCamera():
if ( !fromUserAction && name.equals( "com.motorola.camera.Camera" ) && Build.MODEL.equals( "XT907" ) )
return;
This is just a work-around, but does keep the camera from hanging up.

Related

problem i'm getting (random order) after select images from gallery

after select multi images from gallery on order selection the images goes to the recycle view on random order not as I select on specific order or sort. for example if I select B then A then C but the code always bring them with random sort or order like A C B and sometimes C A B. . the order seems undefined at first I thought android sort them based on date and time added to the gallery or what their name i mean alphabet letter but then I realize the order seems undefined. i'm not sure if I need to add listener with array track the user selections. any suggestion
ArrayList imagesUriArrayList;
public static final int slect_photo = 100;
Bitmap bitmap1 = null;
RecyclerView rec;
LinearLayoutManager lnm;
Adopter_Browse list;
ArrayList<MyCard> mylist;
public void Onclick_View(View view) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);//
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(intent, slect_photo);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (data.getData() != null) {//data.getData() != null) {
imagesUriArrayList = null;
imagesUriArrayList = new ArrayList();
try{
for (int i = 0; i < data.getClipData().getItemCount(); i++) {
imagesUriArrayList.add(data.getClipData().getItemAt(i).getUri());
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG).show();
}
try {
for (int i = 0; i < imagesUriArrayList.size(); i++) {
bitmap1 = MediaStore.Images.Media.getBitmap(this.getContentResolver(), (Uri) imagesUriArrayList.get(i));
mylist.add(new MyCard(count_s, bitmap1));
}
} catch (IOException e) {
e.printStackTrace();
}
lnm = new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false);
list = new Adopter_Browse(mylist);
rec.setLayoutManager(lnm);
list.notifyDataSetChanged();
rec.setAdapter(list);
}
I found out that using onActivityResult that provided by google will always return the order of your selection on miss , so maybe a bug or need improve .
I got two option :
1- using ItemTouchHelper library ... helped me to solve my problem !
2- gradle source form githup !
I share this maybe some one can get relief !

BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: .jpg (No such file or directory)

Good morning, I'm creating activity which take picture then store it in file. But I had this error :
BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: .jpg (No such file or directory)
Also I want to know how to store this picutre file into my room db I have a class "Photo".
Thank you.
Here is my code:
takepictureActivity
public class PrendrePhoto extends AppCompatActivity {
private ImageView imageView;
private EditText titrImg2;
private Button take;
private String pathPic;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prendre_photo);
imageView = (ImageView) findViewById(R.id.imageTaken);
titrImg2 = findViewById(R.id.titreImg2);
take = findViewById(R.id.take);
take.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takePicture();
}
});
}
private void takePicture() {
Intent takepic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takepic.resolveActivity(getPackageManager()) != null) {
File pic = null;
pic = creerPhotoFile();
if (pic != null) {
pathPic = pic.getPath();
System.out.println("pic créer");
System.out.println(pathPic);
startActivityForResult(takepic, 1);
}else {
System.out.println("pic null");
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent
data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == 1) {
Bitmap photo = BitmapFactory.decodeFile(pathPic);
imageView.setImageBitmap(photo);
}
}
//Hna je dois crée filePhoto
}
private File creerPhotoFile() {
ZonedDateTime now = ZonedDateTime.now();
String d = ("" + now.getDayOfMonth() + "/" + now.getMonthValue() +
"/" + now.getYear());
String heure = "" + now.getHour() + " : " + now.getMinute();
String titre = titrImg2.getText().toString();
File temp = new File("temp");
temp.mkdirs();
System.out.println(temp.getPath());
File image = null;
/* try {
image = File.createTempFile(titre, ".jpg",temp);//Even with this
it didn't work
} catch (IOException e) {
e.printStackTrace();
}*/
image = new File(titre + ".jpg");
return image;
}
}
Photo.java
#Entity
public class Photo implements Serializable
{
#PrimaryKey(autoGenerate = true)
private int idP;
private String titre;
private String path ;//this path to get to help to display this picture
private String dateHeure ;
public Photo(String titre, String dateHeure) {
this.titre = titre;
this.dateHeure = dateHeure;
}
}
Even after doing all the logic of creating a unique file path you are using
String titre = titrImg2.getText().toString();
Which is (as per the name suggest) image title, which is coming form UI.
image = new File(titre + ".jpg");
return image;
I think you need to look into this.
As far as saving images in room goes, it is not recommended. But if you have to do it then you can use BLOB.
Images are usually stored as a BLOB and room does provide this
datatype. BLOB Documentation
Implementation can be done like:
#ColumnInfo(typeAffinity = ColumnInfo.BLOB)
private byte[] image;
}

Android - no app found to open link within Edittext

If I click on the HYPERLINK, I get a dialog with the message that no app was found to handle this link, but I know that my android device has some applications to handle this file, becuase I open this file already by click the file itself. Here the code snippet:
case DragEvent.ACTION_DROP:
final String DATA = event.getClipData().getItemAt(0).getText().toString();
final String RECORDS_DIR = ((ScribeApplication ) getApplication()).RECORDS_DIRECTORY_ABSOLUTE_PATH;
final Spanned HYPERLINK = Html.fromHtml("" + RECORDS_DIR + DATA + "");
editor.setMovementMethod(LinkMovementMethod.getInstance());
if (editor.length() > 0)
{
editor.append("\n");
editor.append(HYPERLINK);
}
else
editor.append(HYPERLINK);
return true;
DATA is the file name e.g. record1.3pg
RECORDS_DIR is the absolute path to the directory with the recording files.
HYPERLINK is the absolute path of a record file.
editor is an instance of Eidttext
As mentioned above, if I navigate to the records directory and click the record file itself I get an app chooser and can select an app to handle this record file. So what I did wrong that I dont get an app chooser by clicking the hyperlink within the edittext but rather an dialog with the failure that no app was found?
Many thanks in advance!
Here is my solution for the issue described by CommonsWare:
public class ClickableIntentURLSpan extends URLSpan
{
private Context context;
private Intent intent;
public ClickableIntentURLSpan(final Context CONTEXT, final String URL, final Intent INTENT)
{
super(URL);
final boolean INPUT_OK = (CONTEXT != null) && (INTENT != null);
if (INPUT_OK)
{
context = CONTEXT;
intent = INTENT;
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
else
throw new IllegalArgumentException("Illegal refer to null.");
}
#Override
public void onClick(final View VIEW)
{
context.startActivity(intent);
}
}
case DragEvent.ACTION_DROP:
final String DATA = event.getClipData().getItemAt(0).getText().toString();
final String RECORDS_DIR = ((ScribeApplication ) getApplication()).RECORDS_DIRECTORY_ABSOLUTE_PATH;
final String ABSOLUTE_URL = "file://" + RECORDS_DIR + '/' + DATA;
final Intent PLAY_RECORD_INTENT = new Intent(Intent.ACTION_VIEW);
final File RECORD_FILE = new File(RECORDS_DIR, DATA);
PLAY_RECORD_INTENT.setDataAndType(Uri.fromFile(RECORD_FILE), "audio/*");
final ClickableIntentURLSpan INTENT_URL = new ClickableIntentURLSpan(getApplicationContext(), ABSOLUTE_URL, PLAY_RECORD_INTENT);
final SpannableString HYPERLINK = new SpannableString(DATA);
HYPERLINK.setSpan(INTENT_URL, 0, DATA.length(), 0);
editor.setMovementMethod(LinkMovementMethod.getInstance());
if (editor.length() > 0)
{
editor.append("\n");
editor.append(HYPERLINK);
}
else
editor.append(HYPERLINK);
return true;

How to get a Result from Image Capture and save it to Shared Preferences in Android

I am building an app in which I want when the user clicks the imageview, the device camera app to launch and take a picture and set it to the imageview. I have accomplished that!!! But when I exit the app and re-open it the image has been deleted. How can I do it so the image is permanent?
My code:
private SessionManager session;
private static final int REQ_CODE = 1152;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private Uri file;
private String fileName = "ImageTaken";
private ImageView imagePhoto;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_data);
session = new SessionManager(getApplicationContext());
session.checkLogin();
HashMap<String, String> user = session.getUserDetails();
Toolbar tb = (Toolbar)findViewById(R.id.topBar);
setSupportActionBar(tb);
String name = user.get(SessionManager.KEY_NAME);
TextView watersName = (TextView)findViewById(R.id.waitersName);
TextView date = (TextView)findViewById(R.id.date);
TextView time = (TextView)findViewById(R.id.time);
watersName.setText(Html.fromHtml("<b>" + name + "</b>"));
Calendar c = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd" + "/" + "mm" + "/" + "yyyy");
String text = dateFormat.format(c.getTime());
date.setText(text);
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
String timeF = timeFormat.format(c.getTime());
time.setText(timeF);
Button btnnewworder = (Button)findViewById(R.id.btnnewworder);
btnnewworder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(UserData.this, Tables.class);
startActivity(intent);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_right);
}
});
Button payment = (Button)findViewById(R.id.btnpayment);
payment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DialogMessageDisplay.displayInfoMessage(UserData.this, "Payment Details", "There was no order made. \n Make an order and then tap the payment button.", AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
}
});
imagePhoto = (ImageView)findViewById(R.id.waiterPhoto);
imagePhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
file = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//file = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, file);
startActivityForResult(intent, REQ_CODE);
}
});
}
OnActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == REQ_CODE){
if(resultCode == RESULT_OK){
imagePhoto.setImageURI(file);
editor.putString(fileName, file.toString());
editor.commit();
Toast.makeText(UserData.this, "Your file has been saved at " + file, Toast.LENGTH_SHORT).show();
}else if(resultCode == RESULT_CANCELED){
Toast.makeText(UserData.this, "Action Cancelled", Toast.LENGTH_SHORT).show();
}
}
}
Thanks in advance!!!
Try this:
1) Initialize these:
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
2) Modify your onCreate() like:
sharedPreferences = getSharedPreferences(fileName, MODE_PRIVATE);
editor = sharedPreferences.edit();
imagePhoto = (ImageView)findViewById(R.id.waiterPhoto);
String commited = sharedPreferences.getString(fileName, null);
if(commited != null) {
imagePhoto.setImageURI(Uri.parse(commited));
}
3) Modify your onActivityResult() like:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == REQ_CODE){
if(resultCode == RESULT_OK){
imagePhoto.setImageURI(file);
editor.putString(fileName, file.toString());
editor.commit();
}else if(resultCode == RESULT_CANCELED){
Toast.makeText(UserData.this, "Action Cancelled", Toast.LENGTH_SHORT).show();
}
}
}
And then you will have your desired effect. Hope it helps!!!
SharedPreferences are not meant for holding quantities of data such as imagery. They are meant for holding information about where an image is, or other small selections that the user has chosen.
If you want to save an image off, then you should do just that. Save the image within a local file within the application and then retrieve it later. You can save the location of that file in a SharedPreference object if you would like for you when you return. If it is only one, then you can replace it with the next one in the same file name the next time a picture is taken. This way you always have the latest image available since the last time that picture is taken; even after you shut down and restart the phone.

Android - getting back to menu from filepicker/browsing screen

I found this file picker online, which the developer said that people could use if they wanted to.
Since I thought the code was easy to understand - I decided to use it and change it a bit for my application.
All credit goes to the original developer (https://github.com/mburman/Android-File-Explore)
loadFileList();
showDialog(DIALOG_LOAD_FILE);
Log.d(TAG, path.getAbsolutePath());
}
private void loadFileList() {
try {
path.mkdirs();
} catch (SecurityException e) {
Log.e(TAG, "unable to write on the sd card ");
}
// Checks whether path exists
if (path.exists()) {
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String filename) {
File sel = new File(dir, filename);
// Filters based on whether the file is hidden or not
return (sel.isFile() || sel.isDirectory())
&& !sel.isHidden();
}
};
String[] fList = path.list(filter);
fileList = new Item[fList.length];
for (int i = 0; i < fList.length; i++) {
fileList[i] = new Item(fList[i], R.drawable.file_icon);
// Convert into file path
File sel = new File(path, fList[i]);
// Set drawables
if (sel.isDirectory()) {
fileList[i].icon = R.drawable.directory_icon;
Log.d("DIRECTORY", fileList[i].file);
} else {
Log.d("FILE", fileList[i].file);
}
}
if (!firstLvl) {
Item temp[] = new Item[fileList.length + 1];
for (int i = 0; i < fileList.length; i++) {
temp[i + 1] = fileList[i];
}
temp[0] = new Item("Up", R.drawable.directory_up);
fileList = temp;
}
} else {
Log.e(TAG, "path does not exist");
}
adapter = new ArrayAdapter<Item>(this,
android.R.layout.select_dialog_item, android.R.id.text1,
fileList) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// creates view
View view = super.getView(position, convertView, parent);
TextView textView = (TextView) view
.findViewById(android.R.id.text1);
// put the image on the text view
textView.setCompoundDrawablesWithIntrinsicBounds(
fileList[position].icon, 0, 0, 0);
// add margin between image and text (support various screen
// densities)
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
textView.setCompoundDrawablePadding(dp5);
return view;
}
};
}
private class Item {
public String file;
public int icon;
public Item(String file, Integer icon) {
this.file = file;
this.icon = icon;
}
#Override
public String toString() {
return file;
}
}
#Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
AlertDialog.Builder builder = new Builder(this);
if (fileList == null) {
Log.e(TAG, "No files loaded");
dialog = builder.create();
return dialog;
}
switch (id) {
case DIALOG_LOAD_FILE:
builder.setTitle("Choose your file");
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
chosenFile = fileList[which].file;
File sel = new File(path + "/" + chosenFile);
if (sel.isDirectory()) {
firstLvl = false;
// Adds chosen directory to list
str.add(chosenFile);
fileList = null;
path = new File(sel + "");
loadFileList();
removeDialog(DIALOG_LOAD_FILE);
showDialog(DIALOG_LOAD_FILE);
Log.d(TAG, path.getAbsolutePath());
}
// Checks if 'up' was clicked
else if (chosenFile.equalsIgnoreCase("up") && !sel.exists()) {
// present directory removed from list
String s = str.remove(str.size() - 1);
// path modified to exclude present directory
path = new File(path.toString().substring(0,
path.toString().lastIndexOf(s)));
fileList = null;
// if there are no more directories in the list, then
// its the first level
if (str.isEmpty()) {
firstLvl = true;
}
loadFileList();
removeDialog(DIALOG_LOAD_FILE);
showDialog(DIALOG_LOAD_FILE);
Log.d(TAG, path.getAbsolutePath());
}
// File picked
else {
chosenFile = fileList[which].file;
File test = new File(path + "/" + chosenFile);
sendback(test);
}
}
});
break;
}
dialog = builder.show();
return dialog;
}
Sorry, if it's a bit too long. But that's the entire file picker which is in the onCreate().
I open it by using this code:
Bundle b = new Bundle();
b.putInt("tallet", 1);
Intent i = new Intent(getApplicationContext(), FileExplore.class);
i.putExtras(b);
startActivityForResult(i, 0);
The code works perfectly. But when I press "back" (onBackPressed), it gives me blank (black) screen if I say finish(); .
Right now I'm using this code:
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Intent backIntent = new Intent(FileExplore.this, AndroidTabLayoutActivity.class);
startActivity(backIntent);
}
Which actually works, but it gives me black screen if I press back once, and then the menu, when I hit the back button again. EDIT: it goes INTO the onBackPressed code on second back-press, not the first.
Here's my onActivityResult code in PhotosActivity (it's a tablayout - photosactivity is just one of the screens):
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
// Bundle b = getIntent().getExtras();
if (resultCode == -1)
{
Bundle b = data.getBundleExtra("FiletoPhoto");
int knappen = b.getInt("number");
String titlen = b.getString("title");
{
Listofsounds los = new Listofsounds();
String shortname = los.puttextonit(titlen, knappen);
putnameinit(shortname,knappen);
}
}
else if (resultCode == 0)
{
//If I press "back" i've made the resultCode to be 0 in the onBackPressed. What should I do here then?
}
}
What should I do so I could just press it once and get back to the menu?
The issue is that when you use this code:
Intent backIntent = new Intent(FileExplore.this, AndroidTabLayoutActivity.class);
startActivity(backIntent);
You are basically creating and starting a new activity of AndroidTabLayoutActivity which already exists, so now there will be two copies of this activity running simultaneously. However, the original activity will be expecting a result as you've called startActivityForResult(). I think the solution to your problem is probably to do a check if the resultCode you are getting back as a onActivityResult is RESULT_OK or whatever successful resultCode you are setting in setResult(...) in FileExplore.
This is really strange because in all of my apps I don't override onBackPressed and yet, I am able to finish the activity without causing any weird side effects.

Categories

Resources