Android Bild in Datenbank speichern

S

sugg1

Neues Mitglied
0
Hallo,
ich habe eine kleine App geschrieben, mit der man verschieden Rezepte speichern kann. Das hat bisher einwandfrei funktioniert. Nun wollte ich diese App um ein "Bild" erweitern.

Leider stürzt die App nun ab, wenn ich auf den Speichern Button drücke, egal ob ich ein Foto mache oder nicht.

Hier der Quellcode möglichst kurz:

Datenbank erstellen:
Code:
 [B][COLOR=#7F0055][FONT=Consolas]private[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]static[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]final[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] String [/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]CREATE_DB[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas] = [/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"CREATE TABLE "[/FONT][/COLOR][COLOR=black][FONT=Consolas] + [/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]TABLE_NAME[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas] + [/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]" (_id INTEGER PRIMARY KEY, name VARCHAR(255), zutaten VARCHAR(255), zubereitung VARCHAR(255), person INTEGER(10), pictureData BLOB);"[/FONT][/COLOR][COLOR=black][FONT=Consolas];[/FONT][/COLOR]
Daten schreiben:
Code:
 [B][COLOR=#7F0055][FONT=Consolas]public[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]void[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] insertData([/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]int[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] id,String name, String zutaten, String zubereitung, [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]int[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] person, [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]byte[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas][] pictureData)[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]       {[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]try[/FONT][/COLOR][/B]
  [COLOR=black][FONT=Consolas]             {[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             SQLiteDatabase db = getWritableDatabase();[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             ContentValues values = [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]new[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] ContentValues();[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             values.put([/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"_id"[/FONT][/COLOR][COLOR=black][FONT=Consolas], id);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             values.put([/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"name"[/FONT][/COLOR][COLOR=black][FONT=Consolas], name);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             values.put([/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"zutaten"[/FONT][/COLOR][COLOR=black][FONT=Consolas], zutaten);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             values.put([/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"zubereitung"[/FONT][/COLOR][COLOR=black][FONT=Consolas], zubereitung);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             values.put([/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"person"[/FONT][/COLOR][COLOR=black][FONT=Consolas], person);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             values.put([/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"pictureData"[/FONT][/COLOR][COLOR=black][FONT=Consolas], Rezept.[I]getPictureData[/I]());[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             db.insert([/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]TABLE_NAME[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas],[/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]null[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas],values);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]}[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]catch[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas](SQLiteException e)[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             {[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]                    Log.[I]e[/I]([/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"DB"[/FONT][/COLOR][COLOR=black][FONT=Consolas], [/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"Fehler"[/FONT][/COLOR][COLOR=black][FONT=Consolas], e);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             }[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]       }[/FONT][/COLOR]

Getter- und Setter Methoden der Klasse Rezept

Code:
 [B][COLOR=#7F0055][FONT=Consolas]public[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]void[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] setPictureData([/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]byte[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas][] pictureData) {[/FONT][/COLOR]
  [I][COLOR=#0000C0][FONT=Consolas]pictureDataDrawable[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas] = ImageUtils.[I]byteToDrawable[/I](pictureData);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]    }[/FONT][/COLOR]
  
  [B][COLOR=#7F0055][FONT=Consolas]public[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]static[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]byte[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas][] getPictureData(){[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]return[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] ImageUtils.[I]drawableToByteArray[/I]([/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]pictureDataDrawable[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]);[/FONT][/COLOR]
Methoden zum Umwandeln von Drawables zu Byte-Arrays in der Klasse ImageUtils
Code:
 [B][COLOR=#7F0055][FONT=Consolas]public[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]static[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]byte[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas][] drawableToByteArray(Drawable d) {[/FONT][/COLOR]
  
  [B][COLOR=#7F0055][FONT=Consolas]if[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] (d != [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]null[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas]) {[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]               Bitmap imageBitmap = ((BitmapDrawable) d).getBitmap();[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]               ByteArrayOutputStream baos = [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]new[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] ByteArrayOutputStream();[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]               imageBitmap.compress(Bitmap.CompressFormat.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]PNG[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas], 100, baos);[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]byte[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas][] byteData = baos.toByteArray();[/FONT][/COLOR]
  
  [B][COLOR=#7F0055][FONT=Consolas]return[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] byteData;[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]           } [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]else[/FONT][/COLOR][/B]
  [B][COLOR=#7F0055][FONT=Consolas]return[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]null[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas];[/FONT][/COLOR]
  
  [COLOR=black][FONT=Consolas]       }[/FONT][/COLOR]
  
  
  [B][COLOR=#7F0055][FONT=Consolas]public[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]static[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] Drawable byteToDrawable([/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]byte[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas][] data) {[/FONT][/COLOR]
  
  [B][COLOR=#7F0055][FONT=Consolas]if[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] (data == [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]null[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas])[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]return[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]null[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas];[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]else[/FONT][/COLOR][/B]
  [B][COLOR=#7F0055][FONT=Consolas]return[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]new[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] [U]BitmapDrawable[/U][U](BitmapFactory.[I]decodeByteArray[/I](data, 0, data.[/U][/FONT][/COLOR][U][COLOR=#0000C0][FONT=Consolas]length[/FONT][/COLOR][/U][U][COLOR=black][FONT=Consolas]))[/FONT][/COLOR][/U][COLOR=black][FONT=Consolas];[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]}[/FONT][/COLOR]
Kamerafunktion in der Klasse MainActivity4:
(entsprechender Button: android:onClick="process")

Code:
 [B][COLOR=#7F0055][FONT=Consolas]public[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]void[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] process(View v) [/FONT][/COLOR][COLOR=#3F7F5F][FONT=Consolas]// [U]Kamerafunktion[/U][/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]       {[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             Intent intent = [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]new[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] Intent(MediaStore.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]ACTION_IMAGE_CAPTURE[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]);[/FONT][/COLOR]
  [COLOR=#0000C0][FONT=Consolas]imageFile[/FONT][/COLOR][COLOR=black][FONT=Consolas] = [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]new[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] File(Environment.[I]getExternalStoragePublicDirectory[/I](Environment.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]DIRECTORY_PICTURES[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]),[/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"test.jpg"[/FONT][/COLOR][COLOR=black][FONT=Consolas]);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             Uri tempuri = Uri.[I]fromFile[/I]([/FONT][/COLOR][COLOR=#0000C0][FONT=Consolas]imageFile[/FONT][/COLOR][COLOR=black][FONT=Consolas]);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             intent.putExtra(MediaStore.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]EXTRA_OUTPUT[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas], tempuri);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             intent.putExtra(MediaStore.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]EXTRA_VIDEO_QUALITY[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas], 1);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             startActivityForResult(intent, 0);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]       }[/FONT][/COLOR]
  
  [COLOR=#646464][FONT=Consolas]@Override[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]protected[/FONT][/COLOR][/B][B][COLOR=#7F0055][FONT=Consolas]void[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] onActivityResult([/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]int[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] requestCode, [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]int[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] resultCode, Intent data)[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]       {[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]if[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas](requestCode == 0)[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             {[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]switch[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] (resultCode)[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]                    {[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]case[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] Activity.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]RESULT_OK[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]:[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]if[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas]([/FONT][/COLOR][COLOR=#0000C0][FONT=Consolas]imageFile[/FONT][/COLOR][COLOR=black][FONT=Consolas].exists())[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]                           {[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]                                  Toast.[I]makeText[/I]([/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]this[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas], [/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"The File was saved at: "[/FONT][/COLOR][COLOR=black][FONT=Consolas] + [/FONT][/COLOR][COLOR=#0000C0][FONT=Consolas]imageFile[/FONT][/COLOR][COLOR=black][FONT=Consolas].getAbsolutePath(), Toast.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]LENGTH_LONG[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]).show();[/FONT][/COLOR]
  
  [I][COLOR=#0000C0][FONT=Consolas]myBitmap[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas] = BitmapFactory.[I]decodeFile[/I]([/FONT][/COLOR][COLOR=#0000C0][FONT=Consolas]imageFile[/FONT][/COLOR][COLOR=black][FONT=Consolas].getAbsolutePath());[/FONT][/COLOR]
  
  [COLOR=black][FONT=Consolas]                                  ImageView iv = (ImageView)findViewById(R.id.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]imageView1[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]                                  iv.setImageBitmap([/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]myBitmap[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]);[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]                           }[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]else[/FONT][/COLOR][/B]
  [COLOR=black][FONT=Consolas]                           {[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]                                  Toast.[I]makeText[/I]([/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]this[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas], [/FONT][/COLOR][COLOR=#2A00FF][FONT=Consolas]"File was not saved"[/FONT][/COLOR][COLOR=black][FONT=Consolas], Toast.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]LENGTH_LONG[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]).show();[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]                           }[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]break[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas];[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]case[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] Activity.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]RESULT_CANCELED[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]:[/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]break[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas];[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]                    }[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]             }[/FONT][/COLOR]
  [COLOR=black][FONT=Consolas]       }[/FONT][/COLOR]
Der Speichern Button in der MainActivity4 schreibt die Daten mit instertData() in die Datenbank und hier kommt die Fehlermeldung

Code:
 [B][COLOR=#7F0055][FONT=Consolas]final[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] Datenbank database = [/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]new[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] Datenbank([/FONT][/COLOR][B][COLOR=#7F0055][FONT=Consolas]this[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas]); [/FONT][/COLOR][COLOR=#3F7F5F][FONT=Consolas]// [U]für[/U] [U]Datenbankfunktion[/U][/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]final[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] EditText et1 = (EditText)findViewById(R.id.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]textView1[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]); [/FONT][/COLOR][COLOR=#3F7F5F][FONT=Consolas]// Name [U]des[/U] [U]Rezepts[/U][/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]final[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] TextView tv1 = (TextView)findViewById(R.id.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]textView2[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]); [/FONT][/COLOR][COLOR=#3F7F5F][FONT=Consolas]// [U]Zutaten[/U][/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]final[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] EditText et2 = (EditText)findViewById(R.id.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]textView6[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]); [/FONT][/COLOR][COLOR=#3F7F5F][FONT=Consolas]// [U]Zubereitung[/U][/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]final[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] EditText et3 = (EditText)findViewById(R.id.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]textView7[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]); [/FONT][/COLOR][COLOR=#3F7F5F][FONT=Consolas]// [U]Personen[/U][/FONT][/COLOR]
  [B][COLOR=#7F0055][FONT=Consolas]final[/FONT][/COLOR][/B][COLOR=black][FONT=Consolas] ImageView iv1 = (ImageView)findViewById(R.id.[/FONT][/COLOR][I][COLOR=#0000C0][FONT=Consolas]imageView1[/FONT][/COLOR][/I][COLOR=black][FONT=Consolas]); [/FONT][/COLOR][COLOR=#3F7F5F][FONT=Consolas]// [U]Bild[/U][/FONT][/COLOR][COLOR=black][FONT=Consolas]

database.insertData([/FONT][/COLOR][COLOR=#0000C0][FONT=Consolas]rezept_id[/FONT][/COLOR][COLOR=black][FONT=Consolas], et1.getText().toString(), tv1.getText().toString(), et2.getText().toString(), Integer.[I]parseInt[/I](et3.getText().toString()), ImageUtils.[I]drawableToByteArray[/I](iv1.getDrawable()));[/FONT][/COLOR]

Logcat Ausgabe:

[FONT=&quot]06-23 15:54:35.243: W/IInputConnectionWrapper(17741): showStatusIcon on inactive InputConnection[/FONT]
[FONT=&quot]06-23 15:54:44.352: D/dalvikvm(17741): GC_FOR_ALLOC freed 126K, 10% free 9760K/10759K, paused 50ms, total 51ms[/FONT]
[FONT=&quot]06-23 15:54:44.542: I/dalvikvm-heap(17741): Grow heap (frag case) to 29.095MB for 19660816-byte allocation[/FONT]
[FONT=&quot]06-23 15:54:44.562: D/dalvikvm(17741): GC_CONCURRENT freed 24K, 4% free 28936K/30023K, paused 3ms+2ms, total 20ms[/FONT]
[FONT=&quot]06-23 15:54:44.562: D/dalvikvm(17741): WAIT_FOR_CONCURRENT_GC blocked 16ms[/FONT]
[FONT=&quot]06-23 15:54:47.055: D/AndroidRuntime(17741): Shutting down VM[/FONT]
[FONT=&quot]06-23 15:54:47.055: W/dalvikvm(17741): threadid=1: thread exiting with uncaught exception (group=0x418472a0)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): FATAL EXCEPTION: main[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): java.lang.NumberFormatException: Invalid int: ""[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at java.lang.Integer.invalidInt(Integer.java:138)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at java.lang.Integer.parseInt(Integer.java:359)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at java.lang.Integer.parseInt(Integer.java:332)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at com.example.favoureat.MainActivity4$2.onClick(MainActivity4.java:106)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at android.view.View.performClick(View.java:4162)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at android.view.View$PerformClick.run(View.java:17082)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at android.os.Handler.handleCallback(Handler.java:615)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at android.os.Handler.dispatchMessage(Handler.java:92)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at android.os.Looper.loop(Looper.java:137)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at android.app.ActivityThread.main(ActivityThread.java:4867)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at java.lang.reflect.Method.invokeNative(Native Method)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at java.lang.reflect.Method.invoke(Method.java:511)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)[/FONT]
[FONT=&quot]06-23 15:54:47.055: E/AndroidRuntime(17741): at dalvik.system.NativeStart.main(Native Method)[/FONT]
[FONT=&quot]06-23 15:54:55.953: I/Process(17741): Sending signal. PID: 17741 SIG: 9[/FONT]


So, ich hoffe da blickt noch jemand durch und kann helfen. Ich denke dass es nur an einer Kleinigkeit liegt?:confused2:

Gruß sugg1
 
java.lang.NumberFormatException: Invalid int: ""
[...]
at com.example.favoureat.MainActivity4$2.onClick(Main Activity4.java:106)

Irgendwo wird ein leerer String in eine Zahl konvertiert, was nicht geht. Vermutlich ist einfach das Person-Textfeld zu diesem Zeitpunkt leer.
 
  • Danke
Reaktionen: sugg1
Volltreffer. Ich habe bei der Vorherigen Änderung vergessen den Fehler abzufangen :) Danke!
 
Hat zwar nichts mit deinem aktuellen Problem zu tun, aber mit deinen zukünftigen Problemen: Du solltest Fotos die von der Kamera aufgenommen wurden besser nicht als Blob in die Datenbank speichern. SQLite performt bei großen Blobs ("groß" beginnt schon ab 100KB, siehe Internal Versus External BLOBs) schlecht. Außerdem liegt das Limit für die Cursor Size ziemlich niedrig (1MB), was sich in einer Exception bemerkbar machen wird wenn du darüber leigtst. Deshalb das Bild lieber als File speichern und in der DB den Pfad zum File.
 
  • Danke
Reaktionen: DagobertDokate
Alles klar, danke für den Tipp!
 
Wie erwaretet kam bei mir die angekündigte Exception, weil die Bilder als BLOB gespeichert waren :biggrin: Jetzt sind alle Bilder unter ihrem "Path" gespeichert.

Jedes Bild hat eine fortlaufende Nummer:

test1.jpg, test2.jpg ...

Beim Erstellen des ersten Rezepts mit Bild hat das super funktioniert.

Beim Erstellen des zweiten Rezepts mit Bild kommt folgende LogCat-Ausgabe:


[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): FATAL EXCEPTION: main[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): java.lang.OutOfMemoryError[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:621)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:387)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:420)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at com.example.favoureat.MainActivity3.onCreate(MainActivity3.java:61)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.app.Activity.performCreate(Activity.java:5047)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2056)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2117)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.app.ActivityThread.access$700(ActivityThread.java:134)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1218)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.os.Handler.dispatchMessage(Handler.java:99)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.os.Looper.loop(Looper.java:137)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at android.app.ActivityThread.main(ActivityThread.java:4867)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at java.lang.reflect.Method.invokeNative(Native Method)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at java.lang.reflect.Method.invoke(Method.java:511)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)[/FONT]
[FONT=&quot]06-24 08:00:37.355: E/AndroidRuntime(19830): at dalvik.system.NativeStart.main(Native Method)[/FONT]



Der Fehler tritt auf, wenn ich ein neues Rezept mit Bild aufrufen möchte.
Beim schließen und wieder öffnen der App funktioniert es dann


Folgender Fehler kam gerade beim schießen eines Fotos...
06-24 08:17:24.523: E/dalvikvm-heap(22936): Out of memory on a 19660816-byte allocation.

[FONT=&quot]
[/FONT]
 
Zuletzt bearbeitet:
Hi,

passt denn das geladene Bild in den Speicher?

Ansonsten:
Eigentlich gibt Java den Speicher selbst frei...
Bei Bitmaps gibts ne Recycle() funktion, weiss aber nicht obs das bei dir bringt.

Ansonsten musst du eben aufpassen, dass du Speichersparend proggst.
Also nicht 5 instanzen des gleichen Bildes im Speicher halten.

Globale Variablen sind ein NO_GO.

Was ist mit der Variable R (Rezept) ist die Global?
Ist Irgendwie ein Bildspeicher Global? (Dann gibt ihn keiner frei)

Beste Grüsse
 
Wenn man der BitmapFactory Optionen zuweist, scheint das Problem gelöst zu sein :)


Code:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
myBitmap = BitmapFactory.decodeFile(pfad, options);
 
Das Problem bei Android ist, das Bilder beim Laden zu Bitmaps entpackt werden. Und die sind größer.

Da der Garbage Collector nur unregelmäßig ausgelöst wird, kann die VM relativ schnell zu klein sein, wenn mehrere Bilder geladen werden. Die VM wächst zwar bei Bedarf, aber wenn man sehr viel Speicher auf einmal anfordert, kann es ein OutOfMemoryException geben.

Die beiden besten Möglichkeiten sind meiner Erfahrung nach:

a) Kleine Bilder
b) Die Methode recycle() aufzurufen. Sprich die Bitmaps frei geben, wenn sie nicht mehr gebraucht werden.
c) Danach den Garbage Collector manuell aufrufen. System.gc()

Meistens reicht das. Und natürlich nicht zu viele Bilder gleichzeitig laden.
 
recycle() wird aber nur für Android Versionen 2.3.3 und niedriger benötigt.

Ansonsten ist das mit den options schon der richtige weg
https://developer.android.com/training/displaying-bitmaps/manage-memory.html

Was System.gc() angeht.
Das bringt auch nur beschränkt was, der Aufruf ist ja asynchron, heißt man kann das 10 mal aufrufen, das ist noch keine garantie dafür, dass die Garbage Collection auch aufgerufen wird bevor man sein nächsten Bild läd.
 
recycle() funktioniert für alle Versionen von Android. Wenn man sauber programmiert, braucht man die Methode natürlich nicht. ;)

System.gc() löst den Garbage Collector nicht aus, es ist nur eine Mitteilung an den GC er möchte bitte so schnell wie möglich das System aufräumen. Man sollte die Methode normalerweise nicht benutzten. Der Gebrauch ist eigentlich immer ein Zeichen, das irgendetwas falsch implementiert wurde.

Meiner Erfahrung tritt OutOfMemoryException meistens auf, wenn mehrere Threads "gleichzeitig" Bilder laden oder speichern. Die beste Methode ist natürlich die Anzahl der aktiven Threads zu beschränken.
 
Ich sagte ja schon mit dem Android bin ich qausi Neuling.
Drum habe ich mich gestern schön schief gelacht über meine Frage (oben)

Was ist mit der Variable R (Rezept) ist die Global?

Ich nehme an, einigen anderen ist es ebenso ergangen.


Nun gut:lol: Sie ist also Global, aber wenigtens Final, also eine Quasikonstante.

Beste Grüsse
 
markus.tullius schrieb:
recycle() funktioniert für alle Versionen von Android. Wenn man sauber programmiert, braucht man die Methode natürlich nicht. ;)
Zumindest unter 2.x braucht man recycle() auch für den saubersten aller sauberen Codes. Dort muss der GC nämlich zweimal laufen um ein nicht recycletes Bitmap vollständig aus dem Heap zu entfernen.

Allgemein zum Laden von Bildern: Liest man in Android ein Bitmap ein beelegt dieses 32 Bit (=4 Byte) Heap Speicher pro Pixel. Ich teste meine Apps immer mit einem alten HTC Wildfire, welches über nur 12 MB Heap Speicher verfügt. Das heißt es würde schon bei einem Bild mit der Auflösung 1500x2000 abstürzen, denn 15000*2000*4=12000000

Deshalb ist es wichtig Kamerabilder nie in der höchstmöglichen Auflösung einzulesen. Ich verwende dafür folgenden Code:

Code:
BitmapFactory.Options options = new BitmapFactory.Options();
//read only the bounds, not the image
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathFrom,options);
// Calculate inSampleSize
sampleSize = calculateInSampleSize(options, width,height);
options.inSampleSize = sampleSize;
options.inJustDecodeBounds = false;


private int calculateInSampleSize(
      BitmapFactory.Options options, int reqWidth, int reqHeight) {
      // Raw height and width of image
      final int height = options.outHeight;
      final int width = options.outWidth;
      int inSampleSize = 1;

       if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value. this will guarantee
            // a final image with both dimensions larger than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
      }

      return inSampleSize;
  }

Zuerst werden die Bounds des Bilds eingelesen, nicht das Bild selbst. Anschließend wird das Verhältnis der Bildauflösung zur festgelegten Mindesauflösung berechnet und inSampleSize so gesetzt, dass das Bild mindestens der Mindestauflösung entspricht, aber nicht zu groß ist.
 

Ähnliche Themen

B
Antworten
6
Aufrufe
1.051
jogimuc
J
S
Antworten
33
Aufrufe
2.670
Sempervivum
S
D
Antworten
23
Aufrufe
2.542
Data2006
D
Zurück
Oben Unten