CursorWindow: Window is full - java

I'm new and after days, maybe I found that I have this issue, I have a very big data in a big listView
W/CursorWindow: Window is full: requested allocation 1432389 bytes, free space 750700 bytes, window size 2097152 bytes
E/CursorWindow: Failed to read row 0, column 0 from a CursorWindow which has 0 rows, 64 columns.
W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x420aeda0)
03-03 15:50:00.162 16239-16239/id.co.bumisentosa.yantek E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
I have read some same issue
android java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow
And I found my issue is my image in blob (byte) will not load into my listView.
Then how can I solve my cameraIntent and save it to a specific folder then put it in database and load it in ListView. I really need your help and by examples. Thank You
What I was use is like this
public void openCamera(int resultCode) {
Inspection_JTR_Fragment_Foto_Tab.gallery = false;
File image = new File(appFolderCheckandCreate(resultCode), "img" + getTimeStamp()
+ ".jpg");
Uri uriSavedImage = Uri.fromFile(image);
id.co.bumisentosa.yantek.fragment_JTM.Inspection_JTM_Fragment_Foto_Tab.cameraImagePath = image.getAbsolutePath();
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
i.putExtra("return-data", true);
startActivityForResult(i, resultCode);
}
private String appFolderCheckandCreate(int resultCode) {
String appFolderPath = "";
File externalStorage = Environment.getExternalStorageDirectory();
switch (resultCode) {
case 1:
if (externalStorage.canWrite()) {
appFolderPath = externalStorage.getAbsolutePath() + "/yantek-babel-android/jtr/Keseluruhan Tiang";
File dir = new File(appFolderPath);
if (!dir.exists()) {
dir.mkdirs();
}
} else {
}
break;
}
return appFolderPath;
}
And save it to database
public boolean onOptionsItemSelected(MenuItem item) {
final int id = item.getItemId();
if (id == R.id.action_upload) {
// Upload data ke server
imageArray = Inspection_JTM_Fragment_Foto_Tab.getimageArray();
imageArray_2 = Inspection_JTM_Fragment_Foto_Tab.getimageArray_2();
databaseHandler.saveTest(new ItemsDetails(
imageArray,
imageArray_2
));
}
return super.onOptionsItemSelected(item);
}
my database
public String saveTest(ItemsDetails details) {
try {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
// cv.put(KEY_ID, post.getId());
// cv.put(KEY_ID, "null");
cv.put(COL_LOCATION_ID, details.getunitID());
cv.put(COL_SECTION_ID, details.getjaringanID());
cv.put(COL_INSPECTION_DATE, details.gettanggalInspeksi());
cv.put(COL_INSPECTION_TYPE_ID, details.gettipeInspeksiID());
cv.put(COL_PHOTO_ENTIRE_PATH, details.getimageArray());
cv.put(COL_PHOTO_ISOLATOR_PATH, details.getimageArray_2());
cv.put(COL_POLE_NO, details.getnoTiang());
cv.put(COL_POLE_IRON, details.gettiangBesi());
cv.put(COL_POLE_CONCRETE, details.gettiangBeton());
cv.put(COL_POLE_WOOD, details.gettiangKayu());
cv.put(COL_POLE_CONDITION_BROKEN, details.getkondisiTiangRetak());
cv.put(COL_POLE_CONDITION_TILT, details.getkondisiTiangMiring());
cv.put(COL_POLE_CONDITION_SHIFT, details.getkondisiTiangPindah());
cv.put(COL_CROSS_ARM_TWIST, details.getcrossArmMelintir());
cv.put(COL_CROSS_ARM_RUST, details.getcrossArmKarat());
cv.put(COL_CROSS_ARM_TILT, details.getcrossArmMiring());
cv.put(COL_ARM_TIE_REPAIR, details.getarmTiePerbaiki());
cv.put(COL_ARM_TIE_RUST, details.getarmTieKarat());
cv.put(COL_ARM_TIE_BRACE, details.getarmTiePasang());
cv.put(COL_ISOLATOR_FULCRUM_R_LEAK, details.getisolatorTumpuRGompel());
cv.put(COL_ISOLATOR_FULCRUM_R_BROKEN, details.getisolatorTumpuRPecah());
cv.put(COL_ISOLATOR_FULCRUM_S_LEAK, details.getisolatorTumpuSGompel());
cv.put(COL_ISOLATOR_FULCRUM_S_BROKEN, details.getisolatorTumpuSPecah());
cv.put(COL_ISOLATOR_FULCRUM_T_LEAK, details.getisolatorTumpuTGompel());
cv.put(COL_ISOLATOR_FULCRUM_T_BROKEN, details.getisolatorTumpuTPecah());
cv.put(COL_ISOLATOR_PULL_R_LEAK, details.getisolatorTarikRGompel());
cv.put(COL_ISOLATOR_PULL_R_BROKEN, details.getisolatorTarikRPecah());
cv.put(COL_ISOLATOR_PULL_S_LEAK, details.getisolatorTarikSGompel());
cv.put(COL_ISOLATOR_PULL_S_BROKEN, details.getisolatorTarikSPecah());
cv.put(COL_ISOLATOR_PULL_T_LEAK, details.getisolatorTarikTGompel());
cv.put(COL_ISOLATOR_PULL_T_BROKEN, details.getisolatorTarikTPecah());
cv.put(COL_ARRESTER_R_BROKEN, details.getarresterRusakR());
cv.put(COL_ARRESTER_S_BROKEN, details.getarresterRusakS());
cv.put(COL_ARRESTER_T_BROKEN, details.getarresterRusakT());
cv.put(COL_CONDUCTOR_R_BUYER, details.getkonduktorRBuyer());
cv.put(COL_CONDUCTOR_R_LOOSE, details.getkonduktorRKendor());
cv.put(COL_CONDUCTOR_S_BUYER, details.getkonduktorSBuyer());
cv.put(COL_CONDUCTOR_S_LOOSE, details.getkonduktorSKendor());
cv.put(COL_CONDUCTOR_T_BUYER, details.getkonduktorTBuyer());
cv.put(COL_CONDUCTOR_T_LOOSE, details.getkonduktorTKendor());
cv.put(COL_CONNECTOR_PG_R_35MM, details.getkonektorPGR35mm());
cv.put(COL_CONNECTOR_PG_R_70MM, details.getkonektorPGR70mm());
cv.put(COL_CONNECTOR_PG_R_150MM, details.getkonektorPGR150mm());
cv.put(COL_CONNECTOR_PG_S_35MM, details.getkonektorPGS35mm());
cv.put(COL_CONNECTOR_PG_S_70MM, details.getkonektorPGS70mm());
cv.put(COL_CONNECTOR_PG_S_150MM, details.getkonektorPGS150mm());
cv.put(COL_CONNECTOR_PG_T_35MM, details.getkonektorPGT35mm());
cv.put(COL_CONNECTOR_PG_T_70MM, details.getkonektorPGT70mm());
cv.put(COL_CONNECTOR_PG_T_150MM, details.getkonektorPGT150mm());
cv.put(COL_BENDING_WIRE_R, details.getbendingWireR());
cv.put(COL_BENDING_WIRE_S, details.getbendingWireS());
cv.put(COL_BENDING_WIRE_T, details.getbendingWireT());
cv.put(COL_ULTRASONIC_R, details.getultrasonicR());
cv.put(COL_ULTRASONIC_S, details.getultrasonicS());
cv.put(COL_ULTRASONIC_T, details.getultrasonicT());
cv.put(COL_GSW_EXIST, details.getgswAda());
cv.put(COL_GSW_NOT_EXIST, details.getgswTidakAda());
cv.put(COL_TREE_EXIST, details.getpohonAda());
cv.put(COL_TREE_NOT_EXIST, details.getpohonTidakAda());
cv.put(COL_LONGITUDE, details.getlongitude());
cv.put(COL_LATITUDE, details.getlatitude());
cv.put(COL_SUGGESTION, details.getSaran());
cv.put(COL_DESCR, details.getketerangan());
db.insert(INSPECTIONS_MV_TABLE_NAME, null, cv);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return getNewTestID();
}

Then how can I solve my cameraIntent and save it to a specific folder
then put it in database and load it in ListView. I really need your
help and by examples.
In short you can't. Although you can store the image in the database you cannot retrieve it from the database because it is too large to fit into a CursorWindow which has a limitation of 2MB (2097152).
The image itself is around 1432389 bytes but the CursorWindow only has 750700 bytes. So as 1432389 is greater than 750700 image (blob) it can't be extracted.
You can get around the issue if you :-
save it to a specific folder, then
save the path (or part of the path) in the database rather than the image, and then
extract the path and then get the image via the path when loading the ListView.

Related

How to clear webview cache when server side content updated?

I have a HTML cache enabled WebView app that sends Javascript fetch request to server and gets images list from server, images on server updating every random hour like: today 11:00, 16:00, tomorrow 14:00, 19:00. Images count is always 20 and their names are always like: 0.png, 1.png, 2.png,... 20.png.
Problem is once when app caches images with names like that, after replacing/updating them with other same name images Web app is not showing them, shows just old first time cached images. I know that i can pass get parameter in javascript code while sending get request like: "site.com?time="+Date.getHours();
But i need cache update only on image update on server
Tried code below to clear cache every day but that is not enought:
//helper method for clearCache() , recursive
//returns number of deleted files
static int clearCacheFolder(final File dir, final int numDays) {
int deletedFiles = 0;
if (dir!= null && dir.isDirectory()) {
try {
for (File child:dir.listFiles()) {
//first delete subdirectories recursively
if (child.isDirectory()) {
deletedFiles += clearCacheFolder(child, numDays);
}
//then delete the files and subdirectories in this dir
//only empty directories can be deleted, so subdirs have been done first
if (child.lastModified() < new Date().getTime() - numDays * DateUtils.DAY_IN_MILLIS) {
if (child.delete()) {
deletedFiles++;
}
}
}
}
catch(Exception e) {
Log.e(TAG, String.format("Failed to clean the cache, error %s", e.getMessage()));
}
}
return deletedFiles;
}
/*
* Delete the files older than numDays days from the application cache
* 0 means all files.
*/
public static void clearCache(final Context context, final int numDays) {
Log.i(TAG, String.format("Starting cache prune, deleting files older than %d days", numDays));
int numDeletedFiles = clearCacheFolder(context.getCacheDir(), numDays);
Log.i(TAG, String.format("Cache pruning completed, %d files deleted", numDeletedFiles));
}

How to count pdf pages in fragment

To count pdf pages in a fragment I use https://github.com/TomRoush/PdfBox-Android but I got an error in line 197.
The error is:
Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2
And my code is:
if (requestCode== 86 && resultCode==RESULT_OK && data!=null){
pdfUri = data.getData(); //return the uri of selected file.
notification.setText(data.getData().getLastPathSegment());
try {
PDFBoxResourceLoader.init(applicationContext);
PDDocument doc = PDDocument.load(applicationContext.getContentResolver().openInputStream(pdfUri));
noOfPages.setText(doc.getNumberOfPages()); //line 197
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getActivity(), "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
getActivity().finish();
}
}else{
Toast.makeText(getActivity(),"Please select a file",Toast.LENGTH_SHORT).show();
}
}
You are setting the text via setText() but that has multiple overloads , especially these 2 are interesting:
final void setText(int resid)
final void setText(CharSequence text)
So you are setting the Number of Pages as the text, but the value is an int - so the upper overload is used. Now the Number of Pages is not going to match any String constant (aka Resources) - that is basically the error.
You wanted to use the 2nd overload. To to that, pass a String instead of int.
either by doc.getNumberOfPages().toString() or by using String.valueOf(doc.getNumberOfPages()).

Get filename from database and use it to populate an ImageView

I'm creating an app which at this point needs to get a filename from a sqlite database, get the image with that filename and insert it in an ImageView, i've created this code right now, but i think i'm doing everything wrong here...
Database db = new Database(getApplicationContext());
SQLiteDatabase readableDatabase = db.getReadableDatabase();
final Cursor curFileName = readableDatabase.rawQuery("select filename from data order by id asc", null);
image = (ImageView) findViewById(R.id.image);
int filename = curFileName.getColumnIndex("filename");
String filenameString = curFileName.getString(filename);
d = Drawable.createFromPath(Environment.getExternalStorageDirectory().toString()+filenameString);
Toast.makeText(getApplicationContext(), filenameString, Toast.LENGTH_SHORT).show();
handleDrawable(d);
yes sorry, this is the exception:
04-09 13:48:16.950: E/AndroidRuntime(30802): FATAL EXCEPTION: main
04-09 13:48:16.950: E/AndroidRuntime(30802): java.lang.RuntimeException: Unable to start activity ComponentInfo{g.d.filer/g.d.filer.Favorites}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 33
you must position the cursor before you can read
int filename = curFileName.getColumnIndex("filename");
if (cur.moveToFirst()) { // position cursor to first item. false: empty resultset
String filenameString = curFileName.getString(filename);
d = Drawable.createFromPath(Environment.getExternalStorageDirectory().toString()+filenameString);
Toast.makeText(getApplicationContext(), filenameString, Toast.LENGTH_SHORT).show();
handleDrawable(d);
...
}
Did you add
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
or
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
in the manifest file.
Because, beginning with Android 4.4, these permissions are not required if you're reading or writing only files that are private to your app. For more information, see
http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
I had edited my answer. I hope this will help u. :D
if (cursor.moveToFirst()){
do{
String data = cursor.getString(cursor.getColumnIndex("filename"));
// here you have to generate Image view and add bitmap to imageview
}while(cursor.moveToNext());
}
cursor.close()

Accessing ArrayList<Mat> across Activities, OpenCV, Android

I am trying to use an ArrayList() across two different Activities. It is declared:
public static ArrayList<Mat> Video = new ArrayList<Mat>();
I read in frames from the camera and when I have 50 I go to my next activity.
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
Mat frame = inputFrame.rgba();
if(Video.size() < 50)
{
Log.i(TAG, "Added frame");
Video.add(frame);
}
else
{
String e = Integer.toString(Video.get(1).cols());
Log.v(TAG1, e);
e = Integer.toString(Video.get(1).rows());
Log.v(TAG1, e);
Intent intent = new Intent(this, Analysis.class);
startActivity(intent);
}
return inputFrame.rgba();
}
The log output for this method is:
11-15 22:53:30.225: V/Values(32362): 800
11-15 22:53:30.225: V/Values(32362): 480
This is the correct height and width for the device this is running on(Galaxy S2).
Then in my next activities onCreate() I directly access "Video":
String e = Integer.toString(HomeScreen.Video.get(1).cols());
Log.v(TAG, e);
String h = Integer.toString(HomeScreen.Video.get(1).rows());
Log.v(TAG, h);
But this time the log reads:
11-15 22:53:30.840: V/Values2:(32362): 800
11-15 22:53:30.840: V/Values2:(32362): 0
So my question is, why is the row() value not 480 in both Logs? I need a List of frames because I am recording all the frames and then in another Activity I am going to operate on them and output the display(which I need to number of rows for).
I replaced the line:
Video.add(frame);
With
Video.add(frame.clone());
and it works perfectly!
I think in the top line i was only copying the header part of the frame and not the entire frame's contents.

Android - add table rows after table loading

I am reading UDP packets and i wanna display that info on UI as table in android app.
Here is my code,
try {
byte buffer[] = new byte[10000];<br/>
InetAddress address = InetAddress.getByName("192.168.xx.xx");<br/>
int port = xxx;<br/>
Log.d("..........","What will Happen ?? ");<br/>
for(int k=0;k<50;k++) { // 50 rows are added , This i wanna make it 5000+ rows so it takes plenty of time to load that table <br/>
DatagramPacket p = new DatagramPacket(buffer, buffer.length, address, port);<br/>
DatagramSocket ds = new DatagramSocket(port);<br/>
Log.d("..........","Perfect Binding .... Waiting for Data");<br/>
ds.receive(p);<br/>
Log.d("..........","Packet Received");<br/>
byte[] data = p.getData();<br/>
String result = "";<br/>
int b[] = new int[data.length];</br>
for (int i=0; i < 150; i++) {<br/>
result += Integer.toString( ( data[i] & 0xff ) + 0x100, 16).substring( 1 );<br/>
result += "_";<br/>
}<br/>
Log.d("Result => ",result); <br/>
TableLayout tl=(TableLayout)findViewById(R.id.TableLayout01);<br/>
TableRow tr=new TableRow(this);
TextView tv= new TextView(this);
TextView tv2 = new TextView(this);
tv.setPadding(5, 0, 5, 0);
tv2.setPadding(5,0,5,0);
String k1 = Integer.toString(k);
tv.setText(k1);
tv2.setText(it_version);
tr.addView(tv);
tr.addView(tv2);
tl.addView(tr,1);
ds.close();
}
} catch (Exception e) {
Log.e("UDP", "Client error", e);
}
If i keep 50 rows am able to display it properly without any time delay, if i put 3000 rows its taking too long time and sometimes app is hanging... I wanna add 50 entries to a table and load the table and again read 50 entries and append to the table without touching any button or anything so i have a table in UI and it will update automatically by reading UDP packets ... how i can achieve that ?? Any clue appreciated.
or once i read the UDP packet i wanna display it on UI[appending to the table],How i can do this ??[Scrolling and all i will take care] please let me know
I already tried using threads but no use
Basically, you need to implement an infinite listview. There are a couple strategies to do this:
You can get all the data and store it in a database and only show the user 50 at a time.
You can fetch only 50 at first and then fetch the next 50 when the user scrolls past them.
You can fetch 100, show 50 and then show next 50 when the user scrolls past the first 50. Pre-fetch the next 100 to show next and so on.
Once you figured out your fetching strategy, you need to implement the actual adapter and listview. Here's a good technique to do this. I would recommend that you don't re-invent the wheel and use this great library called EndlessAdapter unless you want to implement it for learning purposes.
Something like this is what you might use in order to get a infinite list effect when you don't have a cursor.
Please note this is a very rough draft since I deleted the code only relevant to my app, to help for you clarity, and for my privacy and the apps privacy. Also it may not be the best way of doing everything, but it worked the first time I wrote it (which took like 10 minutes) and worked beautifully for a very complex list, so I haven't bothered coming back to it.
class AsyncGetUpdates extends AsyncTask<Void, Void, List<UpdateDTO>>
{
#Override
protected void onPreExecute()
{
showDialog();
super.onPreExecute();
}
#Override
protected List<UpdateDTO> doInBackground(Void... params)
{
return APIHelper.getUpdates(count);
}
#Override
protected void onPostExecute(List<UpdateDTO> result)
{
killDialog();
isCurrentlyUpdating = false;
setAdapterData(result);
super.onPostExecute(result);
}
}
public void setAdapterData(List<UpdateDTO> result)
{
killDialog();
if (this != null && this.getActivity() != null)
{
Log.d(TAG, "setAdapterData");
if (lvUpdatesList.getAdapter() != null)
{
// save index and top position
int index = lvUpdatesList.getFirstVisiblePosition();
View v = lvUpdatesList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
updateListAdapter = new UpdateListAdapter(this.getActivity().getLayoutInflater(), result, this);
lvUpdatesList.setAdapter(updateListAdapter);
lvUpdatesList.refreshDrawableState();
lvUpdatesList.setSelectionFromTop(index, top);
}
else
{
updateListAdapter = new UpdateListAdapter(this.getActivity().getLayoutInflater(), result, this);
lvUpdatesList.setAdapter(updateListAdapter);
lvUpdatesList.refreshDrawableState();
}
}
// add in a listener to know when we get to the bottom
lvUpdatesList.setOnScrollListener(new OnScrollListener()
{
#Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
// we do not want to update if we already are
if (isCurrentlyUpdating == false)
{
if (lvUpdatesList.getAdapter() != null && lvUpdatesList.getAdapter().getCount() == count)
{
final int lastItem = firstVisibleItem + visibleItemCount;
if (lastItem == totalItemCount)
{
isCurrentlyUpdating = true;
// add to the count of views we want loaded
count += 20;
// start a update task
new AsyncGetUpdates().execute();
}
}
}
}
});
}
Finally I would like to say that copy pasting might get you the results you want, but it will hinder you future ability. I would say study, read, learn, try, fail, and try again.

Categories