I have this code for update:
public Boolean update() {
try {
data.put(ContactsContract.Groups.SHOULD_SYNC, true);
ContentResolver cr = ctx.getContentResolver();
Uri uri = ContentUris.withAppendedId(ContactsContract.Groups.CONTENT_URI, Long.parseLong(getId()));
int mid = cr.update(uri, data,_ID+"="+getId(), null);
// notify registered observers that a row was updated
ctx.getContentResolver().notifyChange(
ContactsContract.Groups.CONTENT_URI, null);
if (-1 == mid)
return false;
return true;
} catch (Exception e) {
Log.v(TAG(), e.getMessage(), e);
return false;
}
}
I have values in data, I double checked, and for some reason the values are nut pushed out. I also ran a cur.requery(); and I am having
<uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission>
EDIT 1
One thing to mention, that I need to use:
data.put(ContactsContract.Groups.SHOULD_SYNC, 1);
as the true value there is not accepted, although that is returned when you check the ContentValues.
Ok, I figured it down too:
SQLiteException: no such column: res_package: , while compiling: UPDATE groups SET sync4=?, sync3=?, sync2=?, group_visible=?, system_id=?, sync1=?, should_sync=?, deleted=?, account_name=?, version=?, title=?, title_res=?, _id=?, res_package=?, sourceid=?, dirty=?, notes=?, account_type=? WHERE _id=20
The weird thing is that, this column is returned when you Query the content provider. I made the queries to use all returned columns, so I need to make this work somehow.
I just made something similar work. Instead of
int mid = cr.update(uri, data,_ID+"="+getId(), null);
use
int mid = cr.update(uri, data,null, null)
your uri already has embedded ID information.
Related
We have to implement a logic to write the unique code generation in Java. The concept is when we generate the code the system will check if the code is already generate or not. If already generate the system create new code and check again. But this logic fails in some case and we cannot able to identify what is the issue is
Here is the code to create the unique code
Integer code = null;
try {
int max = 999999;
int min = 100000;
code = (int) Math.round(Math.random() * (max - min + 1) + min);
PreOrders preObj = null;
preObj = WebServiceDao.getInstance().preOrderObj(code.toString());
if (preObj != null) {
createCode();
}
} catch (Exception e) {
exceptionCaught();
e.printStackTrace();
log.error("Exception in method createCode() - " + e.toString());
}
return code;
}
The function preOrderObj is calling a function to check the code exists in the database if exists return the object. We are using Hibernate to map the database functions and Mysql on the backend.
Here is the function preOrderObj
PreOrders preOrderObj = null;
List<PreOrders> preOrderList = null;
SessionFactory sessionFactory =
(SessionFactory) ServletActionContext.getServletContext().getAttribute(HibernateListener.KEY_NAME);
Session Hibernatesession = sessionFactory.openSession();
try {
Hibernatesession.beginTransaction();
preOrderList = Hibernatesession.createCriteria(PreOrders.class).add(Restrictions.eq("code", code)).list(); // removed .add(Restrictions.eq("status", true))
if (!preOrderList.isEmpty()) {
preOrderObj = (PreOrders) preOrderList.iterator().next();
}
Hibernatesession.getTransaction().commit();
Hibernatesession.flush();
} catch (Exception e) {
Hibernatesession.getTransaction().rollback();
log.debug("This is my debug message.");
log.info("This is my info message.");
log.warn("This is my warn message.");
log.error("This is my error message.");
log.fatal("Fatal error " + e.getStackTrace().toString());
} finally {
Hibernatesession.close();
}
return preOrderObj;
}
Please guide us to identify the issue.
In createCode method, when the random code generated already exist in database, you try to call createCode again. However, the return value from the recursive call is not updated to the code variable, hence the colliding code is still returned and cause error.
To fix the problem, update the method as
...
if (preObj != null) {
//createCode();
code = createCode();
}
...
Such that the code is updated.
By the way, using random number to generate unique value and test uniqueness through query is a bit strange. You may try Auto Increment if you want unique value.
What Happened
All the data from last month was corrupted due to a bug in the system. So we have to delete and re-input these records manually. Basically, I want to delete all the rows inserted during a certain period of time. However, I found it difficult to scan and delete millions of rows in HBase.
Possible Solutions
I found two way to bulk delete:
The first one is to set a TTL, so that all the outdated record would be deleted automatically by the system. But I want to keep the records inserted before last month, so this solution does not work for me.
The second option is to write a client using the Java API:
public static void deleteTimeRange(String tableName, Long minTime, Long maxTime) {
Table table = null;
Connection connection = null;
try {
Scan scan = new Scan();
scan.setTimeRange(minTime, maxTime);
connection = HBaseOperator.getHbaseConnection();
table = connection.getTable(TableName.valueOf(tableName));
ResultScanner rs = table.getScanner(scan);
List<Delete> list = getDeleteList(rs);
if (list.size() > 0) {
table.delete(list);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != table) {
try {
table.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static List<Delete> getDeleteList(ResultScanner rs) {
List<Delete> list = new ArrayList<>();
try {
for (Result r : rs) {
Delete d = new Delete(r.getRow());
list.add(d);
}
} finally {
rs.close();
}
return list;
}
But in this approach, all the records are stored in ResultScanner rs, so the heap size would be huge. And if the program crushes, it has to start from the beginning.
So, is there a better way to achieve the goal?
Don't know how many 'millions' you are dealing with in your table, but the simples thing is to not try to put them all into a List at once but to do it in more manageable steps by using the .next(n) function. Something like this:
for (Result row : rs.next(numRows))
{
Delete del = new Delete(row.getRow());
...
}
This way, you can control how many rows get returned from the server via a single RPC through the numRows parameter. Make sure it's large enough so as not to make too many round-trips to the server, but at the same time not too large to kill your heap. You can also use the BufferedMutator to operate on multiple Deletes at once.
Hope this helps.
I would suggest two improvements:
Use BufferedMutator to batch your deletes, it does exactly what you need – keeps internal buffer of mutations and flushes it to HBase when buffer fills up, so you do not have to worry about keeping your own list, sizing and flushing it.
Improve your scan:
Use KeyOnlyFilter – since you do not need the values, no need to retrieve them
use scan.setCacheBlocks(false) - since you do a full-table scan, caching all blocks on the region server does not make much sense
tune scan.setCaching(N) and scan.setBatch(N) – the N will depend on the size of your keys, you should keep a balance between caching more and memory it will require; but since you only transfer keys, the N could be quite large, I suppose.
Here's an updated version of your code:
public static void deleteTimeRange(String tableName, Long minTime, Long maxTime) {
try (Connection connection = HBaseOperator.getHbaseConnection();
final Table table = connection.getTable(TableName.valueOf(tableName));
final BufferedMutator mutator = connection.getBufferedMutator(TableName.valueOf(tableName))) {
Scan scan = new Scan();
scan.setTimeRange(minTime, maxTime);
scan.setFilter(new KeyOnlyFilter());
scan.setCaching(1000);
scan.setBatch(1000);
scan.setCacheBlocks(false);
try (ResultScanner rs = table.getScanner(scan)) {
for (Result result : rs) {
mutator.mutate(new Delete(result.getRow()));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
Note the use of "try with resource" – if you omit that, make sure to .close() mutator, rs, table, and connection.
Like you see in this code, I want to get all the information about friends in twitter, people I follow.
But doing this :
PagableResponseList<User> users = twitter.getFriendsList(USER_ID, CURSOR);
... only gives me the first 20 recent friends... What can I do?
Complete code about it :
PagableResponseList<User> users = twitter.getFriendsList(USER_ID, CURSOR);
User user = null;
max = users.size();
System.out.println("Following: "+max);
for (int i = 0 ; i < users.size() ; i++){
user = users.get(i);
System.out.print("\nID: "+user.getId()+" / User: "+user.getName()+" /");
System.out.print("\nFollowers: "+user.getFollowersCount()+"\n");
tid.add(Long.parseLong(String.valueOf(user.getId())));
tusername.add(user.getName());
tfollowers.add(Long.parseLong(String.valueOf(user.getFollowersCount())));
tname.add(user.getScreenName());
}
Thanks..
you can try this code to get the list of people you follow.
long cursor = -1;
PagableResponseList<User> users;
while ((cursor = followers.getNextCursor()) != 0);
{
users = twitter.getFriendsList(userId, cursor);
}
I've taken a peek at the documentation at Twitter4J and Twitter themselves and it's all about that cursor.
To prevent you're getting loaded with a whole bunch of friends at once, Twitter only returns the first 20 results. It doesn't return just the first 20 results, but it also returns a cursor. That cursor is just a random number that's managed by Twitter. When you make a call again and pass this cursor, the next 20 entries (friends) will be returned, again with a cursor that's different now. You can repeat this until the cursor returned is zero. That means there are no more entries available.
In case you want to know more, check these two links: Twitter DEV and Twitter4J documentation.
Concerning your Java, you just need to find a way to get the current cursor, and pass that cursor to your method again, making the app load the next 20 entries. According to this piece of information, that should do the trick.
List<User> allUsers = new ArrayList<User>();
PagableResponseList<User> users;
long cursor = -1;
while (cursor != 0) {
users = twitter.getFriendsList(USER_ID, cursor);
cursor = users.getNextCursor();
allUsers.add(users);
}
You should be able to request up to 200 results at a time:
final PagableResponseList<User> users = twitter.getFriendsList(USER_ID, cursor, 200);
cursor = users.getNextCursor();
If you need to start from where you left off between invocations of your program then you need to store the value of cursor somewhere.
Improvements to Sander's answer!
You can set a count value to the getFriendsList method as in Jonathan's Answer. The maximum value allowed for count is 200. The loop construct will help to collect more than 200 friends now. 200 friends per page or per iteration!
Yet, there are rate limits for any request you make. The getFriendsList method will use this api endpoint: GET friends/list which has a rate limit of 15 hits per 15 minutes. Each hit can fetch a maximum of 200 friends which equates to a total of 3000 friends (15 x 200 = 3000) per 15 minutes. So, there will be no problem if you have only 3000 friends. If you have more than 3000 friends, an exception will be thrown. You can use the RateLimitStatus class to avoid that exception. The following code is an example implementation to achieve this.
Method 1: fetchFriends(long userId)
public List<User> fetchFriends(long userId) {
List<User> friends = new ArrayList<User>();
PagableResponseList<User> page;
long cursor = -1;
try {
while (cursor != 0) {
page = twitter.getFriendsList(userId, cursor, 200);
friends.addAll(page);
System.out.println("Total number of friends fetched so far: " + friends.size());
cursor = page.getNextCursor();
this.handleRateLimit(page.getRateLimitStatus());
}
} catch (TwitterException e) {
e.printStackTrace();
}
return friends;
}
Method 2: handleRateLimit(RateLimitStatus rls)
private void handleRateLimit(RateLimitStatus rls) {
int remaining = rls.getRemaining();
System.out.println("Rate Limit Remaining: " + remaining);
if (remaining == 0) {
int resetTime = rls.getSecondsUntilReset() + 5;
int sleep = (resetTime * 1000);
try {
if(sleep > 0) {
System.out.println("Rate Limit Exceeded. Sleep for " + (sleep / 1000) + " seconds..");
Thread.sleep(sleep);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
By doing so, your program will sleep for some time period based on the rate limiting threshold. It will continue to run from where it left after the sleep. This way we can avoid our program stopping in the midway of collecting friends counting more than 3000.
I have the solution to my post... thanks to Sander, give me some ideas...
The thing was change the for to while ((CURSOR = ids.getNextCursor()) != 0);.
And... user = twitter.showUser(id);
Playing with showUser makes it possible to get, with a slowly time, all the info about all my friends...
That's all. Don't use user.get(i);
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.
I am trying to delete all call logs of particular number.
try {
String strNumberOne[] = {number};
Cursor cursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, CallLog.Calls.NUMBER + "=? ", strNumberOne, "");
boolean bol = cursor.moveToFirst();
if (bol) {
do {
int idOfRowToDelete = cursor.getInt(cursor.getColumnIndex(CallLog.Calls._ID));
getContentResolver().delete(Uri.withAppendedPath(CallLog.Calls.CONTENT_URI, String.valueOf(idOfRowToDelete)), "", null);
} while (cursor.moveToNext());
}
} catch (Exception ex) {
System.out.print("Exception here ");
}
I want to fire a LIKE query, because the mobNum saved in callLog is +916666666666 and i am passing number 6666666666. so its not matching. can anybody help me to overcome this issue?
Try this code to delete any particular number from history
String number="4666";//any number
Uri CALLLOG_URI = Uri.parse("content://call_log/calls");
context.getContentResolver().delete(CALLLOG_URI,CallLog.Calls.NUMBER +"=?",new String[]{number});
you can also delete call log by user name by doing this
context.getContentResolver().delete(CALLLOG_URI,CallLog.Calls.CACHED_NAME +"=?",new String[]{name});
Check the following links:
Call log deletion in Android
SO: Delete call from call log after call end