Related
I am trying offline sync in my azure mobile app but it always returns null pointer.I been debugging to reach the root of error for 3 days but cannot figure it out.Any help will be highly appreciated.Every time i debug i get this error,I have followed the same steps provided by Microsoft azre.
My class is
public class User {
#com.google.gson.annotations.SerializedName("id")
private String mId;
#com.google.gson.annotations.SerializedName("phonenumber")
private String mText;
#com.google.gson.annotations.SerializedName("email")
private boolean mComplete;
#com.google.gson.annotations.SerializedName("name")
private String mName;
public User() {
}
#Override
public String toString() {
return getText();
}
public User(String text, String id) {
this.setText(text);
this.setId(id);
}
public String getText() {
return mText;
}
public final void setText(String text) {
mText = text;
}
public String getId() {
return mId;
}
public final void setId(String id) {
mId = id;
}
public boolean isComplete() {
return mComplete;
}
public void setComplete(boolean complete) {
mComplete = complete;
}
#Override
public boolean equals(Object o) {
return o instanceof User && ((User) o).mId == mId;
}}
and my activity is
public class ToDoActivity extends Activity {
/**
* Mobile Service Client reference
*/
private MobileServiceClient mClient;
//Offline Sync
/**
* Mobile Service Table used to access and Sync data
*/
private MobileServiceSyncTable<User> mToDoTable;
/**
* Adapter to sync the items list with the view
*/
private ToDoItemAdapter mAdapter;
/**
* EditText containing the "New To Do" text
*/
private EditText mTextNewToDo;
/**
* Progress spinner to use for table operations
*/
private ProgressBar mProgressBar;
/**
* Initializes the activity
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_do);
mProgressBar = (ProgressBar) findViewById(R.id.loadingProgressBar);
// Initialize the progress bar
mProgressBar.setVisibility(ProgressBar.GONE);
try {
// Create the Mobile Service Client instance, using the provided
// Mobile Service URL and key
mClient = new MobileServiceClient(
"https://housewrench.azurewebsites.net",
this).withFilter(new ProgressFilter());
// Extend timeout from default of 10s to 20s
mClient.setAndroidHttpClientFactory(new OkHttpClientFactory() {
#Override
public OkHttpClient createOkHttpClient() {
OkHttpClient client = new OkHttpClient();
client.setReadTimeout(20, TimeUnit.SECONDS);
client.setWriteTimeout(20, TimeUnit.SECONDS);
return client;
}
});
// Get the Mobile Service Table instance to use
// mToDoTable = mClient.getTable(ToDoItem.class);
// mUserTable = mClient.getTable(User.class);
// Offline Sync
mToDoTable = mClient.getSyncTable("User", User.class);
//Init local storage
initLocalStore().get();
mTextNewToDo = (EditText) findViewById(R.id.textNewToDo);
// Create an adapter to bind the items with the view
mAdapter = new ToDoItemAdapter(this, R.layout.row_list_to_do);
ListView listViewToDo = (ListView) findViewById(R.id.listViewToDo);
listViewToDo.setAdapter(mAdapter);
// Load the items from the Mobile Service
refreshItemsFromTable();
} catch (MalformedURLException e) {
createAndShowDialog(new Exception("There was an error creating the Mobile Service. Verify the URL"), "Error");
} catch (Exception e){
createAndShowDialog(e, "Error");
}
}
/**
* Initializes the activity menu
*/
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
/**
* Select an option from the menu
*/
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_refresh) {
refreshItemsFromTable();
}
return true;
}
/**
* Mark an item as completed
*
* #param item
* The item to mark
*/
public void checkItem(final ToDoItem item) {
if (mClient == null) {
return;
}
// Set the item as completed and update it in the table
item.setComplete(true);
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
#Override
protected Void doInBackground(Void... params) {
try {
checkItemInTable(item);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (item.isComplete()) {
mAdapter.remove(item);
}
}
});
} catch (final Exception e) {
createAndShowDialogFromTask(e, "Error");
}
return null;
}
};
runAsyncTask(task);
}
/**
* Mark an item as completed in the Mobile Service Table
*
* #param item
* The item to mark
*/
public void checkItemInTable(ToDoItem item) throws ExecutionException, InterruptedException {
//mToDoTable.update(item).get();
}
/**
* Add a new item
*
* #param view
* The view that originated the call
*/
public void addItem(View view) {
if (mClient == null) {
return;
}
// Create a new item
final ToDoItem item = new ToDoItem();
item.setText(mTextNewToDo.getText().toString());
item.setComplete(false);
// Insert the new item
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
#Override
protected Void doInBackground(Void... params) {
try {
final ToDoItem entity = addItemInTable(item);
runOnUiThread(new Runnable() {
#Override
public void run() {
if(!entity.isComplete()){
mAdapter.add(entity);
}
}
});
} catch (final Exception e) {
createAndShowDialogFromTask(e, "Error");
}
return null;
}
};
runAsyncTask(task);
mTextNewToDo.setText("");
}
/**
* Add an item to the Mobile Service Table
*
* #param item
* The item to Add
*/
public ToDoItem addItemInTable(ToDoItem item) throws ExecutionException, InterruptedException {
// ToDoItem entity = mToDoTable.insert(item).get();
return item;
}
/**
* Refresh the list with the items in the Table
*/
private void refreshItemsFromTable() {
// Get the items that weren't marked as completed and add them in the
// adapter
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
#Override
protected Void doInBackground(Void... params) {
try {
//final List<User> results = refreshItemsFromMobileServiceTable();
//Offline Sync
final List<User> results = refreshItemsFromMobileServiceTableSyncTable();
runOnUiThread(new Runnable() {
#Override
public void run() {
mAdapter.clear();
for (User item : results) {
//mAdapter.add(item);
}
}
});
} catch (final Exception e){
createAndShowDialogFromTask(e, "Error");
}
return null;
}
};
runAsyncTask(task);
}
/**
* Refresh the list with the items in the Mobile Service Table
*/
private List<User> refreshItemsFromMobileServiceTable() throws
ExecutionException, InterruptedException {
return mUserTable.where().field("name").
eq(val("noor")).execute().get();
}
//Offline Sync
/**
* Refresh the list with the items in the Mobile Service Sync Table
*/
private List<User> refreshItemsFromMobileServiceTableSyncTable() throws
ExecutionException, InterruptedException {
//sync the data
sync().get();
Query query = QueryOperations.field("phonenumber").
eq(val(false));
return mToDoTable.read(query).get();
}
/**
* Initialize local storage
* #return
* #throws MobileServiceLocalStoreException
* #throws ExecutionException
* #throws InterruptedException
*/
private AsyncTask<Void, Void, Void> initLocalStore() throws MobileServiceLocalStoreException, ExecutionException, InterruptedException {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
MobileServiceSyncContext syncContext = mClient.getSyncContext();
if (syncContext.isInitialized())
return null;
SQLiteLocalStore localStore = new SQLiteLocalStore(mClient.getContext(), "MyStore", null, 1);
Map<String, ColumnDataType> tableDefinition = new HashMap<String, ColumnDataType>();
tableDefinition.put("id", ColumnDataType.String);
tableDefinition.put("phonenumber", ColumnDataType.String);
tableDefinition.put("name", ColumnDataType.String);
tableDefinition.put("email", ColumnDataType.String);
localStore.defineTable("User", tableDefinition);
SimpleSyncHandler handler = new SimpleSyncHandler();
syncContext.initialize(localStore, handler).get();
} catch (final Exception e) {
createAndShowDialogFromTask(e, "Error");
}
return null;
}
};
return runAsyncTask(task);
}
//Offline Sync
/**
* Sync the current context and the Mobile Service Sync Table
* #return
*/
private AsyncTask<Void, Void, Void> sync() {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
#Override
protected Void doInBackground(Void... params) {
try {
MobileServiceSyncContext syncContext = mClient.getSyncContext();
syncContext.push().get();
mToDoTable.pull(null).get();
} catch (final Exception e) {
createAndShowDialogFromTask(e, "Error");
}
return null;
}
};
return runAsyncTask(task);
}
/**
* Creates a dialog and shows it
*
* #param exception
* The exception to show in the dialog
* #param title
* The dialog title
*/
private void createAndShowDialogFromTask(final Exception exception, String title) {
runOnUiThread(new Runnable() {
#Override
public void run() {
createAndShowDialog(exception, "Error");
}
});
}
/**
* Creates a dialog and shows it
*
* #param exception
* The exception to show in the dialog
* #param title
* The dialog title
*/
private void createAndShowDialog(Exception exception, String title) {
Throwable ex = exception;
if(exception.getCause() != null){
ex = exception.getCause();
}
createAndShowDialog(ex.getMessage(), title);
}
/**
* Creates a dialog and shows it
*
* #param message
* The dialog message
* #param title
* The dialog title
*/
private void createAndShowDialog(final String message, final String title) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message);
builder.setTitle(title);
builder.create().show();
}
/**
* Run an ASync task on the corresponding executor
* #param task
* #return
*/
private AsyncTask<Void, Void, Void> runAsyncTask(AsyncTask<Void, Void, Void> task) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
return task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
return task.execute();
}
}
private class ProgressFilter implements ServiceFilter {
#Override
public ListenableFuture<ServiceFilterResponse> handleRequest(ServiceFilterRequest request, NextServiceFilterCallback nextServiceFilterCallback) {
final SettableFuture<ServiceFilterResponse> resultFuture = SettableFuture.create();
runOnUiThread(new Runnable() {
#Override
public void run() {
if (mProgressBar != null) mProgressBar.setVisibility(ProgressBar.VISIBLE);
}
});
ListenableFuture<ServiceFilterResponse> future = nextServiceFilterCallback.onNext(request);
Futures.addCallback(future, new FutureCallback<ServiceFilterResponse>() {
#Override
public void onFailure(Throwable e) {
resultFuture.setException(e);
}
#Override
public void onSuccess(ServiceFilterResponse response) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (mProgressBar != null) mProgressBar.setVisibility(ProgressBar.GONE);
}
});
resultFuture.set(response);
}
});
return resultFuture;
}
}
}
Based on your code, it seems that you have followed the Azure mobile apps quickstart sample for android and adjusted the ToDoItem to your User. I noticed that you did not set properly getter and setter for your name column, and the definition for your email column is String, but your assigned it to the boolean mComplete.
I would recommend you check the offline sync against your ToDoItem table is correctly. And you'd better set breakpoints to the catch code block to see which task throws the exception and check the relevant code to narrow this issue. If you could not solve this issue, you could update your question with the specific code line(s) that threw the exception and the detailed exception info for us to troubleshoot this issue.
int globalPosition ;
..............
buttonAllData.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new UploadBulkData(globalPosition).execute();
}
});
........
class UploadBulkData extends AsyncTask<String, String, String> {
private ProgressDialog pDialog;
int dataPosition;
public UploadBulkData(int position){
this.dataPosition = position;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UploadActivity.this);
pDialog.setMessage("Uploading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
.......
String url = "http://web/uploadBulk.php";
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("UserData", st));
String resultServer = getHttpPost(url,params);
Log.d("Entire string::", " " + resultServer);
/*** Default Value ***/
strStatusID = "0";
strError = "";
JSONObject jsonObject;
try {
jsonObject = new JSONObject(resultServer);
strStatusID = jsonObject.getString("StatusID");
strError = jsonObject.getString("Message");
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
fileNameDB=ImageList.get(globalPosition).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
if(strStatusID.equals("1"))
{
Toast.makeText(UploadActivity.this, "Data Uploaded Successfully", Toast.LENGTH_SHORT).show();
long saveImge = myDbbv.InsertData(fileNameDB);
Log.d("fileNameDB:UP", String.valueOf(saveImge));
}
else
{
Toast.makeText(UploadActivity.this, "Unable to upload Data", Toast.LENGTH_SHORT).show();
}
if (file_url != null){
Toast.makeText(UploadActivity.this, file_url, Toast.LENGTH_LONG).show();
}
}
}
And in getView i am using something like this:
public View getView(final int position, View convertView, ViewGroup parent) {
holder.dataImageView.setImageResource(R.drawable.bullet_button);
try {
// check data exist or not
boolean strDataExistU = myDbbv.Exists(fileNameDB);
if(strDataExistU)
{
holder.dataImageView.setImageResource(R.drawable.online);
}
else
{
boolean strDataExist = myDb.Exists(fileNameDB);
if(strDataExist)
{
holder.dataImageView.setImageResource(R.drawable.local);
}
else
{
holder.dataImageView.setImageResource(R.drawable.default);
}
}
} catch (Exception e) {
}
}
As you can see in getView(...) method, I am using three different kind of drawables (namely:- online, local, default)
Where online shows data has been uploaded to online server, local shows this has been added to local database and default..(neither uploaded to server nor stored to local database)
Problem:
Whenever I am doing bulk upload, getting online drawable only for the last row item in a list, whereas I have uploaded whole list item data to server
I just want to show online drawable for all the list items, those I have uploaded to server, else my code works just fine...
Almost complete code:
public class UploadActivity extends Activity {
int globalPosition ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload);
ImageButton buttonAllData = (ImageButton) findViewById(R.id.btnMenus);
buttonAllData.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new UploadBulkData(globalPosition).execute();
}
});
/*** Get Images from SDCard ***/
ImageList = getSD();
// ListView and imageAdapter
lstView = (ListView) findViewById(R.id.listView1);
lstView.setAdapter(new ImageAdapter(this));
totalItems = ""+ lstView.getAdapter().getCount();
}
public static List <String> getSD()
{
List <String> it = new ArrayList <String>();
String string = "/mnt/sdcard/Pictures/Joseph/";
f = new File (string+ CameraLauncherActivity.folder+ "/");
files = f.listFiles ();
/***
* to show last taken image on top using lastModified
* to sort data
* to refresh data after (remove or update)
*/
Arrays.sort(files, new Comparator<Object>()
{
public int compare(Object o1, Object o2) {
if (((File)o1).lastModified() > ((File)o2).lastModified()) {
return -1;
} else if (((File)o1).lastModified() < ((File)o2).lastModified()) {
return +1;
} else {
return 0;
}
}
});
// <<<<<<<<< END >>>>>>>>>>>
for (int i = 0; i < files.length; i++)
{
file = files[i];
Log.d("Count",file.getPath());
it.add (file.getPath());
}
return it;
}
static class ViewHolder {
public ViewHolder(View convertView) {
// TODO Auto-generated constructor stub
}
TextView imageNameTextView;
ImageView sdCardImageView, statusImageView, dataImageView;
ProgressBar uploadProgressBar;
ImageButton uploadImageButton, dataImageButton;
boolean isUploading = false;
}
public class ImageAdapter extends BaseAdapter
{
public ImageAdapter(Context c)
{
}
public int getCount() {
// TODO Auto-generated method stub
return ImageList.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// Avoid unneccessary calls to findViewById() on each row, which is expensive!
holder = null;
// If this item is to be synced
if(flags.get(position)) {
startUpload(position);
// Mark as synced
flags.put(position, false);
}
/*
* If convertView is not null, we can reuse it directly, no inflation required!
* We only inflate a new View when the convertView is null.
*/
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.list_upload, null);
holder = new ViewHolder(convertView);
// Create a ViewHolder and store references to the children views
holder.imageNameTextView = (TextView) convertView.findViewById(R.id.ColImgName);
holder.sdCardImageView = (ImageView) convertView.findViewById(R.id.ColImgPath);
holder.statusImageView = (ImageView) convertView.findViewById(R.id.ColStatus);
holder.uploadProgressBar = (ProgressBar) convertView.findViewById(R.id.progressBar);
holder.uploadImageButton = (ImageButton) convertView.findViewById(R.id.btnUpload);
holder.dataImageButton = (ImageButton) convertView.findViewById(R.id.btnData);
holder.dataImageView = (ImageView) convertView.findViewById(R.id.dataExist);
// The tag can be any Object, this just happens to be the ViewHolder
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
strPath = ImageList.get(position).toString();
// Get File Name
fileName = strPath.substring( strPath.lastIndexOf('_')+1, strPath.length() );
file = new File(strPath);
#SuppressWarnings("unused")
long length = file.length();
holder.imageNameTextView.setText(fileName);
fileName=ImageList.get(position).toString().substring
(strPath.lastIndexOf('_')+1, strPath.length());
fileNameDB=ImageList.get(position).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bm = BitmapFactory.decodeFile(strPath,options);
holder.sdCardImageView.setImageBitmap(bm);
if(holder.isUploading) {
holder.uploadProgressBar.setVisibility(View.VISIBLE);
} else {
holder.uploadProgressBar.setVisibility(View.GONE);
}
holder.dataImageView.setImageResource(R.drawable.bullet_button);
try {
// check data exist or not
boolean strDataExistU = myDbbv.Exists(fileNameDB);
if(strDataExistU)
{
holder.dataImageView.setImageResource(R.drawable.online);
}
else
{
// check data exist or not
boolean strDataExist = myDb.Exists(fileNameDB);
if(strDataExist)
{
holder.dataImageView.setImageResource(R.drawable.database);
}
else
{
holder.dataImageView.setImageResource(R.drawable.default);
}
}
} catch (Exception e) {
// TODO: handle exception
}
fileName = ImageList.get(position).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
try {
boolean strExist = myDbb.Exists(fileName);
if(strExist)
{
holder.statusImageView.setImageResource(R.drawable.onl);
}
else
{
holder.statusImageView.setImageResource(R.drawable.bullet_button);
}
} catch (Exception e) {
// TODO: handle exception
}
// btnData
holder.dataImageButton.setOnClickListener(new View.OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View v) {
// Print
globalPosition = position;
fileName=ImageList.get(position).toString().substring
(strPath.lastIndexOf('_')+1, strPath.length());
fileNameDB=ImageList.get(position).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
showDialog(DIALOG_LOGIN);
}
});
return convertView;
}
}
class UploadData extends AsyncTask<String, String, String> {
private ProgressDialog pDialog;
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UploadActivity.this);
pDialog.setMessage("Uploading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
String url = "http://web/uploadData.php";
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("sImageName", fileNameDB));
Log.d("sImageName::", fileNameDB);
String resultServer = getHttpPost(url,params);
Log.d("Entire string::", " " + resultServer);
/*** Default Value ***/
strStatusID = "0";
strError = "";
JSONObject c;
try {
c = new JSONObject(resultServer);
strStatusID = c.getString("StatusID");
strError = c.getString("Error");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once product deleted
pDialog.dismiss();
try {
fileName=ImageList.get(globalPosition).toString().substring
(strPath.lastIndexOf('_')+1, strPath.length());
fileNameDB=ImageList.get(globalPosition).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
// prepare save data
if(strStatusID.equals("0"))
{
Toast.makeText(getApplicationContext(), "Unable to upload Data",
Toast.LENGTH_LONG).show();
}
else if (strStatusID.equals("1"))
{
Toast.makeText(getApplicationContext(), "Data Uploaded Successfully!",
Toast.LENGTH_SHORT).show();
// Save Data
long saveImge = myDbbv.InsertData(fileNameDB);
Log.d("fileNameDB:UP", String.valueOf(saveImge));
} else {
Toast.makeText(getApplicationContext(), "Unable to upload Data",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// TODO: handle exception
}
if (file_url != null){
Toast.makeText(UploadActivity.this, file_url, Toast.LENGTH_LONG).show();
}
}
}
});
cancelButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
closeButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
}
}
class UploadBulkData extends AsyncTask<String, String, String> {
private ProgressDialog pDialog;
int dataPosition;
//constructor to pass position of row, on which button was clicked to class
public UploadBulkData(int position){
this.dataPosition = position;
}
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UploadActivity.this);
pDialog.setMessage("Uploading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
String url = "http://web/uploadBulk.php";
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("EventData", st));
String resultServer = getHttpPost(url,params);
Log.d("Entire string::", " " + resultServer);
/*** Default Value ***/
strStatusID = "0";
strError = "";
JSONObject jsonObject;
try {
jsonObject = new JSONObject(resultServer);
strStatusID = jsonObject.getString("StatusID");
strError = jsonObject.getString("Message");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once product deleted
pDialog.dismiss();
// Prepare Save Data
if(strStatusID.equals("1"))
{
Toast.makeText(UploadActivity.this, "Data Uploaded Successfully", Toast.LENGTH_SHORT).show();
fileNameDB=ImageList.get(dataPosition).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
// Save Data
long saveImge = myDbbv.InsertData(fileNameDB);
Log.d("fileNameDB:UP", String.valueOf(saveImge));
}
else
{
Toast.makeText(UploadActivity.this, "Unable to upload Data", Toast.LENGTH_SHORT).show();
}
if (file_url != null){
Toast.makeText(UploadActivity.this, file_url, Toast.LENGTH_LONG).show();
}
}
}
Issue is in holder.dataImageButton.setOnClickListener method block, position value you are assigning to globalPosition (globalPosition = position;) is the one passed to getView method (getView is called every time view is recycled). So you should set position to holder.dataImageButton tag and retrieve from it inside your setOnClickListener method block.
So set the position in holder.dataImageButton tag
holder.dataImageButton.setTag(position);
after your code line
holder.dataImageView.setImageResource(R.drawable.bullet_button);
and modify your setOnClickListener method as
holder.dataImageButton.setOnClickListener(new View.OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View v) {
// Print
globalPosition = (Integer)v.getTag(); //modified
fileName=ImageList.get(position).toString().substring
(strPath.lastIndexOf('_')+1, strPath.length());
fileNameDB=ImageList.get(position).toString().substring
(strPath.lastIndexOf('/')+1, strPath.length());
showDialog(DIALOG_LOGIN);
}
});
It appears that in both UploadData and UploadBulkData the exact same code is used for updating the uploaded database: myDbbv.InsertData(fileNameDB). This would have the effect of only marking the last file of UploadBulkData as being uploaded, which is consistent with the problematic behavior you are seeing.
Try updating myDbbv for each file being uploaded in UploadData and see if it helps.
There could be multiple customizable ways to achieve this. One of them is already answered. Correct me if I'm wrong about your requirement, you need to be notified when the list reached its last item. Afterwards, you're going to perform an operation with the last item index.
[UPDATE]
For this solution: You have to migrate to Recycler View as it's more flexible, fast and optimised for bulk data.
int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition(); // This function could be the one you're looking for.
int findLastCompletelyVisibleItemPosition();
Usage:
// In Java
GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
Reference: https://stackoverflow.com/a/25053500/16176653
I'm calling async tasks in a loop on the onPostExecute() of an asyncTask. I want the control to wait until response of all the tasks is not receieved cause I'm collecting the response in a single arrayList which i have to pass a callback method after all the asyncTasks called in the loop are finished.
I'm avoiding to use the AsyncTask.get() as it blocks the main thread.
public class CallServerAsync extends AsyncTask<AsyncHttpRequestBo, Void, ArrayList<ArrayList<AsyncHttpRequestBo>>> implements PlatwareResponseListener {
PlatwareClientCommonUtils clientCommonFunctions;
Context context;
String url;
PlatwareResponseListener listener;
private ProgressDialog progressDialog;
ArrayList<AsyncHttpResponseBo> processResponseList = null;
ArrayList<AsyncHttpResponseBo> responseList = null;
public CallServerAsync(Context context, PlatwareResponseListener listener) {
this.context = context;
clientCommonFunctions = new PlatwareClientCommonUtils(context);
url = clientCommonFunctions.getServerUrlPrimary();
this.listener = listener;
responseList = new ArrayList<AsyncHttpResponseBo>();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(context, "Please wait", "Downloading...");
}
#Override
protected ArrayList<ArrayList<AsyncHttpRequestBo>> doInBackground(AsyncHttpRequestBo... params) {
ArrayList<ArrayList<AsyncHttpRequestBo>> requestLists = clientCommonFunctions.generateRequestList(params);
return requestLists;
}
#Override
protected void onPostExecute(ArrayList<ArrayList<AsyncHttpRequestBo>> result) {
for (ArrayList<AsyncHttpRequestBo> httpRequestList : result) {
CallserverSubAsync callserverSubAsync = new CallserverSubAsync(context, this);
callserverSubAsync.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, httpRequestList);
// ArrayList<AsyncHttpResponseBo> processResponseList = null;
// try {
// processResponseList = callserverSubAsync.get();
// } catch (InterruptedException e) {
// e.printStackTrace();
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
}
listener.onAsyncTaskCompleted(responseList, listener);
progressDialog.dismiss();
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
progressDialog.dismiss();
super.onCancelled();
}
#Override
public void onAsyncTaskCompleted(ArrayList<AsyncHttpResponseBo> responseList, PlatwareResponseListener listener) {
if (listener instanceof CallServerAsync) {
processResponseList = responseList;
for (AsyncHttpResponseBo responseBo : processResponseList) {
this.responseList.add(responseBo);
}
}
}
Here is my code:
private void downloadSupplyTownData(final int townId2) {
/*******************
* Using Volley
*******************/
// Post params to be sent to the server
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("ID",townId2);
CustomDialogClass.showProgressDialog(context,true);
JsonObjectRequest req = new JsonObjectRequest(Consts.baseUrl+Consts.townSupplyUrl, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
totalConsumerRecords = Integer.parseInt(response.getString("TotalConsumerRecords").trim());
if(totalConsumerRecords>0)
{
/**For -----**/
JSONArray dtrArray = response.getJSONArray("xxx");
for(int i=0;i<dtrArray.length();i++)
{
JSONObject dtrObj = dtrArray.getJSONObject(i);
supplyId1 = Integer.parseInt(dtrObj.getString("SI"));
dtrId = Integer.parseInt(dtrObj.getString("DI"));
dtrImgUrl = dtrObj.getString("DIMG");
dtrCode = dtrObj.getString("DC");
assetPCode = dtrObj.getString("APC");
meterSN = dtrObj.getString("MSN");
System.out.println(dtrId);
db.addDtrInfo(new DTRBeanClass(dtrId,supplyId1,dtrCode,dtrImgUrl,assetPCode,meterSN));
}
/**For ----**/
JSONArray poleArray = response.getJSONArray("Pole");
for(int i=0;i<poleArray.length();i++)
{
JSONObject poleObj = poleArray.getJSONObject(i);
poleId = Integer.parseInt(poleObj.getString("PI"));
dtrId1 = Integer.parseInt(poleObj.getString("DI"));
consumerCount = Integer.parseInt(poleObj.getString("ACA"));
poleImgUrl = poleObj.getString("PIMG");
poleCode = poleObj.getString("PC");
surveyerRemarks = poleObj.getString("RMS");
System.out.println(poleId);
db.addPoleInfo(new PoleBeanClass(poleId,dtrId1,poleCode,poleImgUrl,consumerCount,surveyerRemarks));
}
/**For ----**/
JSONArray consumerArray = response.getJSONArray("Supply");
for(int i=0;i<consumerArray.length();i++)
{
JSONObject supplyObj = consumerArray.getJSONObject(i);
supplyId = Integer.parseInt(supplyObj.getString("SI"));
supplyTownId = Integer.parseInt(supplyObj.getString("TI"));
supplyName = supplyObj.getString("SN");
System.out.println(supplyId);
db.addSupplierInfo(new SupplierChainBeanClass(supplyId,supplyTownId,supplyName));
}
CustomDialogClass.showProgressDialog(context,false);
}
else
{
CustomDialogClass.showProgressDialog(context,false);
}
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
VolleyLog.e("Error: ", error.getMessage());
Log.d("Eroor", ""+networkResponse);
CustomDialogClass.showProgressDialog(context,false);
}
});
// add the request object to the queue to be executed
NameApplication.getInstance().addToRequestQueue(req);
}
Here show and hide ProgressDialog by CustomDialogClass.showProgressDialog(context,true);
Progress dialog spin first 2-3 seconds and then stuck. Please help me out to handle this.
EDIT
/**
* Showing Dialog
* */
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case progress_bar_type: // we set this to 0
pDialog = new ProgressDialog(this);
pDialog.setMessage("Downloading file. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setMax(100);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setCancelable(true);
pDialog.show();
return pDialog;
default:
return null;
}
}
/**
* Background Async Task to download file
* */
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread
* Show Progress Bar Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... f_url) {
downloadSupplyTownData(townId);
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task
* Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
dismissDialog(progress_bar_type);
}
}
And from view call the AsynchTask new DownloadFileFromURL().execute();
Progress dialog spin first 2-3 seconds and then stuck.
Because parsing of json response and downloadConsumerData method making api request from main UI Thread.
In Volley onResponse method called as callback method on main UI Thread when network request is completed.
For parsing request response in onResponse method use AsyncTask class and call ProgressDialog dismiss method in onPostExecute method which will close ProgressDialog when Volley request, parsing of json data and downloadConsumerData method job is done in background Thread
Start AsyncTask from onResponse method :
#Override
public void onResponse(JSONObject response) {
new DownloadFileFromURL().execute(response);
}
In doInBackground process JSON data:
#Override
protected String doInBackground(String... f_url) {
totalConsumerRecords = Integer.parseInt(response.getString
("TotalConsumerRecords").trim());
// add all code here from onResponse
downloadSupplyTownData(townId);
return null;
}
I have some images in my view pager and i am deleting images from delete button,but after deleting image i want to refresh view pager and and want to display remaining image in my application can any one what is mistake?
public class PhotoView extends Activity{
private Button btn;
private String User_IDs;
private String total;
private String max;
ArrayList<Integer> userImgidArrayList;
ArrayList<String> userstatusArrayList;
ArrayList<String> userphotoArrayList;
private ImageView imageView;
private Button btndelete;
private Button btnsetprofilepic;
int singlepicid;
// Progress Dialog
private ProgressDialog pDialog;
JSONParser jsonParser = new JSONParser();
private static final String DELT_SETPRO_URL = "my url";
private static final String DELT_SETPRO_STATUS = "status";
private static final String DELT_SETPRO_MSG = "msg";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photoview);
User_IDs=this.getIntent().getStringExtra("id");
System.out.println("photo upload view user id"+User_IDs);
IMAGE_URL="my url"+User_IDs;
total=this.getIntent().getStringExtra("totals");
System.out.println("photo total "+total);
max=this.getIntent().getStringExtra("maxs");
System.out.println("photo maximum "+max);
userImgidArrayList = getIntent().getIntegerArrayListExtra("photoid");
System.out.println(userImgidArrayList);
userstatusArrayList=getIntent().getStringArrayListExtra("imgstatus");
System.out.println(userstatusArrayList);
userphotoArrayList=getIntent().getStringArrayListExtra("pics");
System.out.println(userphotoArrayList);
for(int i=0;i< userImgidArrayList.size();i++)
{
singlepicid=userImgidArrayList.get(i);
System.out.println(singlepicid);
}
for(int i=0;i< userphotoArrayList.size();i++)
{
String singleimage=userphotoArrayList.get(i);
System.out.println(singleimage);
}
for(int i=0;i< userstatusArrayList.size();i++)
{
String singlestatus=userstatusArrayList.get(i);
System.out.println(singlestatus);
}
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
ImageAdapter adapter = new ImageAdapter(this);
viewPager.setAdapter(adapter);
imageView = (ImageView) findViewById(R.id.full_image_views);
btn=(Button)findViewById(R.id.goforupload);
btn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent=new Intent(getApplicationContext(),PhotoUpload.class);
intent.putExtra("id", User_IDs);
startActivity(intent);
}
});
btndelete=(Button)findViewById(R.id.deleteimage);
btndelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
singlepicid = userImgidArrayList.get(viewPager.getCurrentItem());
new AttemptLogin().execute();
userphotoArrayList.remove(viewPager.getCurrentItem());
// adapter.notifyDataSetChanged();
viewPager.getAdapter().notifyDataSetChanged();
}
});
btnsetprofilepic=(Button)findViewById(R.id.setprofilepic);
btnsetprofilepic.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
public class ImageAdapter extends PagerAdapter {
Context context;
ImageAdapter(Context context)
{
this.context=context;
}
#Override
public int getCount() {
return userphotoArrayList.size();
}
#Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((ImageView) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(
R.dimen.activity_horizontal_margin);
imageView.setPadding(padding, padding, padding, padding);
//imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
Picasso.with(context).load(userphotoArrayList.get(position)).into(imageView);
((ViewPager) container).addView(imageView, 0);
return imageView;
}
#Override
public int getItemPosition(Object object) {
viewPager.setAdapter(adapter);
return POSITION_NONE;
}
}
class AttemptLogin extends AsyncTask<String, String, String> {
boolean failure = false;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(PhotoView.this);
pDialog.setMessage("Loading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String...args) {
//Check for success tag
String btnmethod=btndelete.getTag().toString();
/*String val=null;
singlepicid=Integer.parseInt(val);*/
Looper.prepare();
try {
//Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("user_login_id", User_IDs));
params.add(new BasicNameValuePair("method", btnmethod));
params.add(new BasicNameValuePair("user_photo_id", String.valueOf(singlepicid)));
params.add(new BasicNameValuePair("version", "apps"));
Log.d("request!", "starting");
// getting product details by making HTTP request
JSONObject json = jsonParser.makeHttpRequest (
DELT_SETPRO_URL, "POST", params);
System.out.println(params);
//check your log for json response
Log.d("Processing", json.toString());
JSONObject jobj = new JSONObject(json.toString());
final String msg = jobj.getString("msg");
System.out.println("MSG : " + msg);
runOnUiThread(new Runnable()
{
#Override
public void run()
{
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
});
return json.getString(DELT_SETPRO_STATUS);
}catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
//dismiss the dialog once product deleted
pDialog.dismiss();
}}
class LoadImages extends AsyncTask<String, String, ArrayList<HashMap<String,String>>> {
String photoid;
int userPhotoId;
String userstatus;
String uploadedpics;
#Override
protected void onPreExecute() {
super.onPreExecute();
prDialog = new ProgressDialog(PhotoView.this);
prDialog.setMessage("Refreshing...");
prDialog.setIndeterminate(false);
prDialog.setCancelable(false);
prDialog.show();
}
protected ArrayList<HashMap<String,String>> doInBackground(String... args) {
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
ArrayList<HashMap<String,String>> data = new ArrayList<HashMap<String, String>>();
String jsonStr = sh.makeServiceCall(IMAGE_URL, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
try {
jsonobj = new JSONObject(jsonStr);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(IMAGE_USERLOGIN_ID, jsonobj.getString(IMAGE_USERLOGIN_ID));
map.put(IMAGE_TOTAL_PHOTO,jsonobj.getString(IMAGE_TOTAL_PHOTO));
map.put(IMAGE_MAX_UPLOAD, jsonobj.getString(IMAGE_MAX_UPLOAD));
final String totalphota = jsonobj.getString("user_total_photo");
Log.d("Value: ", "> " + totalphota);
final String maximumphota = jsonobj.getString("max_upload_photo");
Log.d("Value: ", "> " + maximumphota);
userImgidArrayList = new ArrayList<Integer>();
image_list = (JSONArray) jsonobj.get("image_list");
for(int i=0;i< image_list.length();i++)
{
JSONObject imageListItem = image_list.getJSONObject(i);
userPhotoId = imageListItem.getInt("user_photo_id");
userImgidArrayList.add(userPhotoId);
Log.d("mylog", "i ="+i+" and user_photo_id =" + userPhotoId);
}
userstatusArrayList = new ArrayList<String>();
image_list = (JSONArray) jsonobj.get("image_list");
for(int i=0;i< image_list.length();i++)
{
JSONObject statusListItem = image_list.getJSONObject(i);
userstatus = statusListItem.getString("status");
userstatusArrayList.add(userstatus);
Log.d("mylog", "i ="+i+" and status =" + userstatus);
}
userphotoArrayList = new ArrayList<String>();
image_list = (JSONArray) jsonobj.get("image_list");
for(int i=0;i< image_list.length();i++)
{
JSONObject photoListItem = image_list.getJSONObject(i);
uploadedpics=photoListItem.getString("photo");
userphotoArrayList.add(uploadedpics);
Log.d("mylog", "i ="+i+" and photo =" + uploadedpics);
}
} catch (JSONException e) {
e.printStackTrace();
}
return data;
}
protected void onPostExecute(ArrayList<HashMap<String,String>> result) {
super.onPostExecute(result);
if (prDialog.isShowing())
prDialog.dismiss();
}
}
Alternatively.. you can Refresh your activity..
try this
On click refresh button
finish();
startActivity(getIntent());
btndelete=(Button)findViewById(R.id.deleteimage);
btndelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
userphotoArrayList.remove(viewPager.getCurrentItem())
adapter.notifyDataSetChanged();
}
});
and also in your adapter:
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
Rewrite all my answer:
Firstly , let's see the usage of AsyncTask, here is important functions:
/**
* Override this method to perform a computation on a background thread. The
* specified parameters are the parameters passed to {#link #execute}
* by the caller of this task.
*
* This method can call {#link #publishProgress} to publish updates
* on the UI thread.
*
* #param params The parameters of the task.
*
* #return A result, defined by the subclass of this task.
*
* #see #onPreExecute()
* #see #onPostExecute
* #see #publishProgress
*/
protected abstract Result doInBackground(Params... params);
/**
* Runs on the UI thread before {#link #doInBackground}.
*
* #see #onPostExecute
* #see #doInBackground
*/
protected void onPreExecute() {
}
/**
* <p>Runs on the UI thread after {#link #doInBackground}. The
* specified result is the value returned by {#link #doInBackground}.</p>
*
* <p>This method won't be invoked if the task was cancelled.</p>
*
* #param result The result of the operation computed by {#link #doInBackground}.
*
* #see #onPreExecute
* #see #doInBackground
* #see #onCancelled(Object)
*/
#SuppressWarnings({"UnusedDeclaration"})
protected void onPostExecute(Result result) {
}
Now , let's see what have you done in AsyncTask , Notice I have change the template of AsyncTask:
class AttemptLogin extends AsyncTask<String, String, int> {
#Override
protected void onPreExecute() {
//Here you have show a dialog with loading message, that's great.
}
#Override
protected int doInBackground(String...args) {
//Here you send http request to delete data on server, and receive response from it.
JSONObject json = jsonParser.makeHttpRequest (
DELT_SETPRO_URL, "POST", params);
System.out.println(params);
//check your log for json response
Log.d("Processing", json.toString());
JSONObject jobj = new JSONObject(json.toString());
final String msg = jobj.getString("msg");
//That's all right so far , bug you haven't confirm whether the server have delete the data you want to .
//So you should write some code to check this
if(msg.equals("Succ")//Just for example
{
//Here you have check the data is already delete by server
//Now you can delete the data store in your code not the server
return viewPager.getCurrentItem();//return the index of viewPager you want to delete to onPostExecute
}
else
{
//something wrong with server , so you shouldn't delete anything
return -1; //Just return -1 let onPostExecute know no one need to be deleted.
}
}
#Override
protected void onPostExecute(int index) {
//Here is in UI Thread
if(index != -1) {
userphotoArrayList.remove(index)//Delete the data with this index
//Now your data have changed but the view haven't changed , you should call notifyDataSetChanged
viewPager.getAdapter().notifyDataSetChanged();
}
else {
//You should let User know he or she delete photo failed
Toast.makeText(PhotoView.this, "Delete failed", Toash.LENGTH_SHORT).show();
}
}
}
And , don't not just copy my code , there is a lot of assumption。