Android ProgressDialog Won't be dismiss after Paytm Transation on success - android

when the paytm WebView calls "back to Activity" return. what should be the Approach to handle waiting for transation Complete.
My progress Dialog opened before Paytm Screen open but When returned from paytm screen to activity progress dialog not dismissing..
please any help or idea about this issue....
1.OnSuccess of transaction i opened paytmcheckout() method
in this method i want to Dismiss or cancel the progressbarDialog.
But it is not dismiss here.
public void paytmCheckout(){
if(_progressDialog.isShowing()) {
_progressDialog.hide();
_progressDialog.dismiss();
}
}
2. progressDialog Declared globally
ProgressDialog _progressDialog;
onButtonClick()
calls openpaytm Method
My OpenPaytm method::
private void openPaytm() {
int price;
if (discount != 0) {
price = modalPlan.getInrPrice() - discount;
} else {
price = modalPlan.getInrPrice();
}
//Here`
//my progressDialog is opened here successfully
//
if(_progressDialog==null){
mLoginFormView.setVisibility(View.INVISIBLE);
final ProgressDialog _progressDialog = ProgressDialog.show(
getActivity(),
"Transation",
"Progress....",
true,
true
);
}
Random randomGenerator = new Random();
randomInt = randomGenerator.nextInt(1000);
Service = PaytmPGService.getStagingService(); //for production environment
PaytmMerchant Merchant = new PaytmMerchant("https://app.mobikyte.com/paytm/generateChecksum.php", "https://app.mobikyte.com/paytm/verifyChecksum.php");
HashMap<String, String> paramMap = new HashMap<>();
paramMap.put("REQUEST_TYPE", "DEFAULT");
paramMap.put("ORDER_ID", "" + modalAddCampign.getOrderId());
paramMap.put("MID", "Audian53591216301431");
paramMap.put("CUST_ID", modalLogin.getClientid());
paramMap.put("CHANNEL_ID", "WAP");
paramMap.put("INDUSTRY_TYPE_ID", "Retail");
paramMap.put("WEBSITE", "AudianzN");
paramMap.put("TXN_AMOUNT", "" + price);
paramMap.put("THEME", "merchant");
String par = paramMap.toString();
Log.e("TESTING:", "Paytm Params" + par);
PaytmOrder Order = new PaytmOrder(paramMap);
Service.initialize(Order, Merchant, null);
Service.startPaymentTransaction(getActivity(), false, false, new PaytmPaymentTransactionCallback() {
#Override
public void onTransactionSuccess(Bundle bundle) {
Log.d("TEST", "Bundle = =" + bundle);
paytmCheckout();
}
#Override
public void onTransactionFailure(String s, Bundle bundle) {
Log.e("Error", "someErrorOccurred :" + s);
//Not dismissing here also
_progressDialog.dismiss();
// _progressDialog.cancel();
}
#Override
public void networkNotAvailable() {
Log.e("Error", "NetworkErrorOccurred :");
}
#Override
public void clientAuthenticationFailed(String s) {
Log.e("Error", "clientAuthenticationFailed :" + s);
}
#Override
public void someUIErrorOccurred(String s) {
Log.e("Error", "someUIErrorOccurred :" + s);
}
#Override
public void onErrorLoadingWebPage(int i, String s, String s1) {
Log.e("Error", "onErrorLoadingWebPage :" + s1);
}
});
}

Related

PayUmoney seamless Integration

experts
can you help me in seemless integration with PayUmoney payment Gateway in android
also if you have any sample of seemless integration please share
i have tried like this but showing me error of Marchentkey and salt is incorrect but i copied both from my account
below is code detail
MainActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Payu.setInstance(this);
proceedtopay();
}
public void proceedtopay(){
PaymentParams mPaymentParams = new PaymentParams();
String merchant_key="rjQUPktU"; // test gtkFFx XmOFYRT3
String salt="e5iIg1jwi8"; // test eCwWELxi aTZEImxcYO
mPaymentParams.setKey(merchant_key);
mPaymentParams.setAmount("15.0");
mPaymentParams.setProductInfo("Tshirt");
mPaymentParams.setFirstName("Waseem");
mPaymentParams.setEmail("waseemahmad241#gmail.com");
mPaymentParams.setTxnId("0123479543689");
mPaymentParams.setSurl("https://www.payumoney.com/mobileapp/payumoney/success.php");
mPaymentParams.setFurl("https://www.payumoney.com/mobileapp/payumoney/failure.php");
mPaymentParams.setUdf1("udf1l");
mPaymentParams.setUdf2("udf2");
mPaymentParams.setUdf3("udf3");
mPaymentParams.setUdf4("udf4");
mPaymentParams.setUdf5("udf5");
String hashSequence = merchant_key+"|0123479543689|15.0|productinfo|Waseem|waseemahmad241#gmail.com|udf1|udf2|udf3|udf4|udf5||||||"+salt;
String serverCalculatedHash= hashCal("SHA-512", hashSequence);
mPaymentParams.setHash(serverCalculatedHash);
mPaymentParams.setCardNumber("4012001037141112");
mPaymentParams.setCardName("test");
mPaymentParams.setNameOnCard("test");
mPaymentParams.setExpiryMonth("05");// MM
mPaymentParams.setExpiryYear("2020");// YYYY
mPaymentParams.setCvv("123");
mPaymentParams.setEnableOneClickPayment(1);
PostData postData = null;
try {
postData = new PaymentPostParams(mPaymentParams, PayuConstants.CC).getPaymentPostParams();
} catch (Exception e) {
e.printStackTrace();
}
if (postData.getCode() == PayuErrors.NO_ERROR) {
// launch webview
PayuConfig payuConfig = new PayuConfig();
payuConfig.setEnvironment(PayuConstants.STAGING_ENV);
payuConfig.setData(postData.getResult());
Intent intent = new Intent(this,PaymentsActivity.class);
intent.putExtra(PayuConstants.PAYU_CONFIG,payuConfig);
startActivityForResult(intent, PayuConstants.PAYU_REQUEST_CODE);
} else {
// something went wrong
Toast.makeText(this,postData.getResult(), Toast.LENGTH_LONG).show();
}
}
public static String hashCal(String type, String hashString) {
StringBuilder hash = new StringBuilder();
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance(type);
messageDigest.update(hashString.getBytes());
byte[] mdbytes = messageDigest.digest();
for (byte hashByte : mdbytes) {
hash.append(Integer.toString((hashByte & 0xff) + 0x100, 16).substring(1));
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return hash.toString();
}
and MyWebview Activity is
PaymentsActivity extends AppCompatActivity {
//String base_url="https://test.payumoney.in/_payment";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web_view);
Bundle bundle =getIntent().getExtras();
PayuConfig payuConfig =bundle.getParcelable(PayuConstants.PAYU_CONFIG);
WebView mWebView =(WebView) findViewById(R.id.webview);
// String url =//payuConfig.getEnvironment() == PayuConstants.PRODUCTION_ENV ? PayuConstants.PRODUCTION_PAYMENT_URL :PayuConstants.MOBILE_TEST_PAYMENT_URL;
byte[] encodedData = EncodingUtils.getBytes(payuConfig.getData(), "base64");
mWebView.postUrl(PayuConstants.TEST_PAYMENT_URL,encodedData);
mWebView.getSettings().setSupportMultipleWindows(true);
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.setWebChromeClient(new WebChromeClient() {});
mWebView.setWebViewClient(new WebViewClient() {});
#SuppressLint("SetJavaScriptEnabled")
public class Payment extends AppCompatActivity {
WebView webView;
Context activity;
int mId;
/*private String mMerchantKey ="your marchant key"
private String mSalt = "your salt key"*/
private String mBaseURL = "https://test.payu.in";
private String mAction = ""; // For Final URL
private String mTXNId; // This will create below randomly
private String mHash; // This will create below randomly
private String mProductInfo = "product name"; //Passing String only
private String mFirstName; // From Previous Activity
private String mEmailId; // From Previous Activity
private double mAmount; // From Previous Activity
private String mPhone; // From Previous Activity
private String mServiceProvider = "";// "payu_paisa";
private String mSuccessUrl = "success url";
private String mFailedUrl = "failure url";
String MAM_ID = "mem_id";
String EMAIL = "email";
String ADD1 = "address_line1";
String ADD2 = "address_line2";
String REGION_ID = "region_id";
String CITY_ID = "city_id";
String PROMOCODE = "promocode";
String PIN_CODE = "pin_code";
String ADD_DATE = "add_date";
String PRICE = "price";
String CARD_DISCOUNT = "card_discount";
String PROMOCODE_DISCOUNT = "promocode_discount";
String TXNID = "tnx_id";
String DEVICE_ID = "device_id";
String PRODUCT_ID = "product_id";
boolean isFromOrder;
/*
Handler
*/
Handler mHandler = new Handler();
Bundle bundle;
SharedPreferences spfs;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
/**
* #param savedInstanceState
*/
#SuppressLint({"AddJavascriptInterface", "SetJavaScriptEnabled", "JavascriptInterface"})
#Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().requestFeature(Window.FEATURE_PROGRESS);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview_for_payumoney);
spfs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
webView = (WebView) findViewById(R.id.payumoney_webview);
activity = getApplicationContext();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
ab.setDisplayHomeAsUpEnabled(true);
// enabling action bar app icon and behaving it as toggle button
ab.setHomeButtonEnabled(true);
ab.setTitle("Payment Gateaway");
bundle = getIntent().getExtras();
if (bundle != null) {
Log.e("Bndle Data:- ", bundle.toString());
mFirstName = bundle.getString("Name");//NAME
mEmailId = bundle.getString("Email");// lOGIN IN PAYUMONEY ID
mAmount = 1.0;//bundle.getDouble("Price");// AMOUNT
mPhone = bundle.getString("Mobile"); // MOBILE ! REQUIRED
mId = 1;//bundle.getInt("id");
isFromOrder = true;// bundle.getBoolean("isFromOrder");
Log.e("Tag payment ", "" + mFirstName + " : " + mEmailId + " : " + mAmount + " : " + mPhone);
Random rand = new Random();
String randomString = Integer.toString(rand.nextInt()) + (System.currentTimeMillis() / 1000L);
mTXNId = hashCal("SHA-256", randomString).substring(0, 20);
mAmount = new BigDecimal(mAmount).setScale(0, RoundingMode.UP).intValue();
mHash = hashCal("SHA-512", mMerchantKey + "|" +
mTXNId + "|" +
mAmount + "|" +
mProductInfo + "|" +
mFirstName + "|" +
mEmailId + "|||||||||||" +
mSalt);
mAction = mBaseURL.concat("/_payment");
try {
Class.forName("com.payu.custombrowser.Bank");
} catch (Exception e) {
}
webView.setWebViewClient(new WebViewClient() {
#SuppressWarnings("deprecation")
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// Handle the error
Log.e("WEB_VIEW_TEST", "error code:" + errorCode);
super.onReceivedError(view, errorCode, description, failingUrl);
}
#TargetApi(Build.VERSION_CODES.M)
#Override
public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {
// Redirect to deprecated method, so you can use it in all SDK versions
onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString());
Log.e("onReceivedError", "error code:" + rerr);
Toast.makeText(activity, "Oh no! " + rerr.getDescription().toString(), Toast.LENGTH_SHORT).show();
}
/*#Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
Toast.makeText(activity, "Oh no! " + error, Toast.LENGTH_SHORT).show();
}*/
#Override
public void onReceivedSslError(WebView view,
SslErrorHandler handler, SslError error) {
Toast.makeText(activity, "SSL Error! " + error, Toast.LENGTH_SHORT).show();
handler.proceed();
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view, url);
}
#Override
public void onPageFinished(WebView view, String url) {
if (url.equals(mSuccessUrl)) {
RecepetUpload();
} else if (url.equals(mFailedUrl)) {
Log.e("Payment STatus", "failure");
Custom_Toast.show(getApplication(), "Payment Transcation Failed");
Intent intent = new Intent(Payment.this, MainActivity.class);
intent.putExtra("status", false);
intent.putExtra("transaction_id", mTXNId);
intent.putExtra("id", mId);
intent.putExtra("isFromOrder", isFromOrder);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
super.onPageFinished(view, url);
}
});
webView.setVisibility(View.VISIBLE);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setCacheMode(2);
webView.getSettings().setDomStorageEnabled(true);
webView.clearHistory();
webView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
webView.clearCache(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSupportZoom(true);
webView.getSettings().setUserAgentString("Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3");
webView.setInitialScale(1);
webView.addJavascriptInterface(new PayUJavaScriptInterface(Payment.this), "PayUMoney");
/**
* Mapping Compulsory Key Value Pairs
*/
Map<String, String> mapParams = new HashMap<>();
mapParams.put("key", mMerchantKey);
mapParams.put("txnid", mTXNId);
mapParams.put("amount", String.valueOf(mAmount));
mapParams.put("productinfo", mProductInfo);
mapParams.put("firstname", mFirstName);
mapParams.put("email", mEmailId);
mapParams.put("phone", mPhone);
mapParams.put("surl", mSuccessUrl);
mapParams.put("furl", mFailedUrl);
mapParams.put("hash", mHash);
mapParams.put("service_provider", mServiceProvider);
Log.e("Url WEb View", mAction);
webViewClientPost(webView, mAction, mapParams.entrySet());
} else {
Toast.makeText(activity, "Something went wrong, Try again.", Toast.LENGTH_LONG).show();
}
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
/**
* Posting Data on PayUMoney Site with Form
*
* #param webView
* #param url
* #param postData
*/
public void webViewClientPost(WebView webView, String url,
Collection<Map.Entry<String, String>> postData) {
StringBuilder sb = new StringBuilder();
sb.append("<html><head></head>");
sb.append("<body onload='form1.submit()'>");
sb.append(String.format("<form id='form1' action='%s' method='%s'>", url, "post"));
for (Map.Entry<String, String> item : postData) {
sb.append(String.format("<input name='%s' type='hidden' value='%s' />", item.getKey(), item.getValue()));
}
sb.append("</form></body></html>");
Log.d("TAG", "webViewClientPost called: " + sb.toString());
webView.loadData(sb.toString(), "text/html", "utf-8");
}
/**
* Hash Key Calculation
*
* #param type
* #param str
* #return
*/
public String hashCal(String type, String str) {
byte[] hashSequence = str.getBytes();
StringBuffer hexString = new StringBuffer();
try {
MessageDigest algorithm = MessageDigest.getInstance(type);
algorithm.reset();
algorithm.update(hashSequence);
byte messageDigest[] = algorithm.digest();
for (int i = 0; i < messageDigest.length; i++) {
String hex = Integer.toHexString(0xFF & messageDigest[i]);
if (hex.length() == 1)
hexString.append("0");
hexString.append(hex);
}
} catch (NoSuchAlgorithmException NSAE) {
}
Log.e("Hex String", "" + hexString);
return hexString.toString();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onPressingBack();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
onPressingBack();
}
/**
* On Pressing Back
* Giving Alert...
*/
private void onPressingBack() {
final Intent intent;
if (isFromOrder)
intent = new Intent(Payment.this, MainActivity.class);
else
intent = new Intent(Payment.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(Payment.this);
// Setting Dialog Title
alertDialog.setTitle("Warning");
// Setting Dialog Message
alertDialog.setMessage("Do you cancel this transaction?");
// On pressing Settings button
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
// Showing Alert Message
alertDialog.show();
}
#Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Payment Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://https://secure.payu.in"),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse("android-app://com.local/https/https://secure.payu.in")
);
AppIndex.AppIndexApi.start(client, viewAction);
}
#Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Payment Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://https://secure.payu.in"),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse("android-app://com.local/https/https://secure.payu.in")
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}
public class PayUJavaScriptInterface {
Context mContext;
/**
* Instantiate the interface and set the context
*/
PayUJavaScriptInterface(Context c) {
mContext = c;
}
public void success(long id, final String paymentId) {
mHandler.post(new Runnable() {
public void run() {
mHandler = null;
Toast.makeText(Payment.this, "Payment Successfully.", Toast.LENGTH_SHORT).show();
}
});
}
}
private void RecepetUpload() {
final ProgressDialog progDialog;
progDialog = ProgressDialog.show(Payment.this, "", "waiting");
try {
if (!progDialog.isShowing()) {
progDialog.show();
}
StringRequest postRequest = new StringRequest(Request.Method.POST,
"http://www.local.com/club-app/api-order-details", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("Payment Status:--", "Success , " + mTXNId);
Custom_Toast.show(getApplication(), "Payment Transcation Success");
Intent intent = new Intent(Payment.this, MainActivity.class);
intent.putExtra("status", true);
intent.putExtra("transaction_id", mTXNId);
intent.putExtra("id", mId);
intent.putExtra("isFromOrder", isFromOrder);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
try {
if (progDialog.isShowing()) {
progDialog.dismiss();
}
Log.e("res Payment", "" + response);
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
if (progDialog.isShowing()) {
progDialog.dismiss();
}
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put(MAM_ID, "" + spfs.getString("mem_id", ""));
params.put(EMAIL, "" + mEmailId);
params.put(ADD1, "" + bundle.getString(ADD1));
params.put(ADD2, "" + bundle.getString(ADD2));
params.put(REGION_ID, "" + bundle.getString(REGION_ID));
params.put(CITY_ID, "" + bundle.getString(CITY_ID));
params.put(PIN_CODE, "" + bundle.getString(PIN_CODE));
params.put(ADD_DATE, "" + bundle.getString(ADD_DATE));
params.put(PRICE, "" + mAmount);
params.put(CARD_DISCOUNT, "" + bundle.getString(CARD_DISCOUNT));
params.put(PROMOCODE_DISCOUNT, "" + bundle.getString(PROMOCODE_DISCOUNT));
params.put(PROMOCODE, "" + bundle.getString(PROMOCODE));
params.put(TXNID, "" + mTXNId);
params.put(DEVICE_ID, "" + Settings.Secure.getString(getApplicationContext().getContentResolver(),
Settings.Secure.ANDROID_ID));
params.put(PRODUCT_ID, "" + bundle.getString(PRODUCT_ID));
Log.e("Bndle Params:- ", params.toString());
return params;
}
};
int socketTimeout = 60000;// 30 seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
postRequest.setRetryPolicy(policy);
Volley.newRequestQueue(this).add(postRequest);
} catch (Exception e) {
if (progDialog.isShowing()) {
progDialog.dismiss();
}
Log.e("", " Exception Occurs - " + e);
}
}
}

Attempt to invoke virtual method xx on a null object reference when I try to reload the activity

I've an activity whuich load some data from mySql db to populate a Recyclerview.
PollActivity.java (relevant code)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_poll);
rv = findViewById(R.id.rv);
// *** Rv Init ***
LinearLayoutManager llm = new LinearLayoutManager(this);
rv.setLayoutManager(llm);
rv.setHasFixedSize(false);
polls = new ArrayList<>();
// SqLite data management
db = new SQLiteHandler(getApplicationContext());
HashMap<String, String> user = db.getUserDetails();
final String userid = user.get("uid");
// Local data
String localBefore = Locale.getDefault().getLanguage().toUpperCase();
final String local;
switch (localBefore){
case "IT":
local = "IT";
break;
case "FR":
local = "FR";
break;
case "DE":
local = "DE";
break;
case "ES":
local = "ES";
break;
default:
local = "EN";
break;
}
// ************
// *** MAIN ***
// ************
// Tag used to cancel the request
String tag_string_req = "req_login";
MaterialDialog.Builder builder = new MaterialDialog.Builder(this)
.title(R.string.strDialogProgressLoading_title)
.content(R.string.strDialogProgressReg_desc)
.progress(true, 0);
final MaterialDialog myDialog = builder.build();
myDialog.show();
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.POLL_LOADING, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
if (!error) {
for(int i=0; i<jObj.length()-2; i++){
int j = i + 1;
JSONObject pollObject = jObj.getJSONObject("poll" + i);
JSONObject pollObjectNext = jObj.getJSONObject("poll" + j);
i++;
//Id to String Translate
int idInterests = getResources().getIdentifier("strInterestsItem" + pollObject.getString("id_interests"), "string", getPackageName());
String strInterests = getString(idInterests);
String strPoint;
if(pollObject.getString("sponsor").equals("UUABA")){
strPoint = "+200";
}else{
strPoint = "+150";
}
//String concatenation
String idPoll = "#" + pollObject.getString("id_poll");
String strQuestion = "#" + pollObject.getString("poll_question");
String IdUser = userid;
polls.add(new Poll(idPoll
, pollObject.getString("sponsor")
, pollObject.getString("poll_user_state")
, IdUser
, strInterests
, strQuestion
, pollObject.getString("poll_answer")
, pollObject.getString("id_poll_answer")
, pollObjectNext.getString("poll_answer")
, pollObjectNext.getString("id_poll_answer")
, strPoint));
}
initializeAdapter();
myDialog.dismiss();
} else {
myDialog.dismiss();
// Error in loading. Get the error message
String errorMsg = jObj.getString("error_msg");
int idErrorRes = getResources().getIdentifier(errorMsg, "string", getPackageName());
String strErrorRes = getString(idErrorRes);
//POPUP ERRORE
new MaterialDialog.Builder(PollActivity.this)
.title(getResources().getString(R.string.strDialogAttention_title))
.titleColor(getResources().getColor(R.color.colorAccentDark))
.content(strErrorRes)
.positiveText(R.string.strDialogBtnPositive)
.contentGravity(GravityEnum.CENTER)
.positiveColor(getResources().getColor(R.color.colorAccent))
.icon(getResources().getDrawable(R.drawable.ic_dialog_alert))
.cancelable(false)
.autoDismiss(false)
.onPositive(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
}
})
.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
myDialog.dismiss();
//POPUP ERRORE
new MaterialDialog.Builder(PollActivity.this)
.title(getResources().getString(R.string.strDialogAttention_title))
.titleColor(getResources().getColor(R.color.colorAccentDark))
.content(getResources().getString(R.string.errorVolley1) + "(" + error + ")")
.positiveText(R.string.strDialogBtnPositive)
.contentGravity(GravityEnum.CENTER)
.positiveColor(getResources().getColor(R.color.colorAccent))
.icon(getResources().getDrawable(R.drawable.ic_dialog_alert))
.cancelable(false)
.autoDismiss(false)
.onPositive(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
}
})
.show();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting parameters to loading url
Map<String, String> params = new HashMap<String, String>();
params.put("userid", userid);
params.put("local", local);
//Log.d("NINJA", "UserID: " + userid);
//Log.d("NINJA", "Local: " + local);
return params;
}
};
// Adding request to request queue
AppVolleyController.getInstance().addToRequestQueue(strReq, tag_string_req);
// ************
// ************
// ************
private void initializeAdapter(){
RVAdapter adapter = new RVAdapter(polls);
rv.setAdapter(adapter);
}
public void reloadActivity(){
startActivity(getIntent());
finish();
}
}
RVAdapter.java(my Recycler View Adapter)
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PollViewHolder> {
public static class PollViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView txtIdPoll;
ImageView imgSponsor;
ImageView imgNew;
TextView txtIdInterests;
TextView txtQuestion;
RadioGroup radioGroupAnswers;
RadioButton radioAnswer1;
RadioButton radioAnswer2;
Button btnPoint;
PollViewHolder(View itemView) {
super(itemView);
cv = itemView.findViewById(R.id.cv);
txtIdPoll = itemView.findViewById(R.id.txtIdPoll);
imgSponsor = itemView.findViewById(R.id.imgSponsor);
imgNew = itemView.findViewById(R.id.imgNew);
txtIdInterests = itemView.findViewById(R.id.txtIdInterests);
txtQuestion = itemView.findViewById(R.id.txtQuestion);
radioGroupAnswers = itemView.findViewById(R.id.radioGroupAnswers);
radioAnswer1 = itemView.findViewById(R.id.radioAnswer1);
radioAnswer2 = itemView.findViewById(R.id.radioAnswer2);
btnPoint = itemView.findViewById(R.id.btnPoint);
}
}
List<Poll> polls;
//Context context;
public RVAdapter(List<Poll> polls){
this.polls = polls;
//this.context = context;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public PollViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.poll_item, viewGroup, false);
PollViewHolder pvh = new PollViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(final PollViewHolder pollViewHolder, final int i) {
final int rb1id = 1000;
final int rb2id = 2000;
//Setting RadioButton ID
pollViewHolder.radioAnswer1.setId(rb1id);
pollViewHolder.radioAnswer2.setId(rb2id);
pollViewHolder.txtIdPoll.setText(polls.get(i).txtIdPoll);
if(polls.get(i).txtSponsor.equals("UUABA")){
pollViewHolder.imgSponsor.setImageResource(R.drawable.ic_logo_red_bg);
}else{
pollViewHolder.imgSponsor.setImageResource(R.drawable.ic_sponsor_green_bg);
}
if(polls.get(i).txtNew.equals("0")){
pollViewHolder.imgNew.setImageResource(R.drawable.ic_new);
}else{
pollViewHolder.btnPoint.setEnabled(false);
pollViewHolder.btnPoint.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_ATOP);
}
pollViewHolder.txtIdInterests.setText(polls.get(i).txtIdInterests);
pollViewHolder.txtQuestion.setText(polls.get(i).txtQuestion);
pollViewHolder.radioAnswer1.setText(polls.get(i).txtAnswer1);
pollViewHolder.radioAnswer2.setText(polls.get(i).txtAnswer2);
pollViewHolder.btnPoint.setText(polls.get(i).txtPoint);
pollViewHolder.btnPoint.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(pollViewHolder.radioGroupAnswers.getCheckedRadioButtonId() == -1){
Snackbar snackbar = Snackbar.make(v, R.string.strSnackPoll, Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView textView =snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.YELLOW);
snackbar.show();
}else{
QueryUtils queryUtils = new QueryUtils();
String IdPoll = String.valueOf((polls.get(i).txtIdPoll)).replace("#", "");
switch (pollViewHolder.radioGroupAnswers.getCheckedRadioButtonId()){
case 1000:
queryUtils.upgPollAnswer(String.valueOf((polls.get(i).txtUserId)), IdPoll, String.valueOf((polls.get(i).txtIdAnswer1)));
break;
case 2000:
queryUtils.upgPollAnswer(String.valueOf((polls.get(i).txtUserId)), IdPoll, String.valueOf((polls.get(i).txtIdAnswer2)));
break;
}
}
}
});
}
#Override
public int getItemCount() {
return polls.size();
}
}
At this point, I would like to update a db field at button click and reload PollActivity.java to force the RecyclerView update (I'd like that the NEW image disappear from the updated CardView). I guess to do this calling a method of my QueryUtils.java (one of the method it will contain), avoiding to write too mutch code inside adapter.
QueryUtils.java
#SuppressLint("Registered")
public class QueryUtils extends Application {
private String tag_string_req = "req_poll_answer_upg";
public void upgPollAnswer(final String UserId, final String PollId, final String AnswerId){
Log.d("NINJA", "Utente: " + UserId);
Log.d("NINJA", "Poll: " + PollId);
Log.d("NINJA", "Risposta: " + AnswerId);
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.POLL_ANSWER_UPG, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
String message = jObj.getString("message");
if (!error) {
Log.d("NINJA", "Messaggio: " + message);
PollActivity pollActivity = new PollActivity();
pollActivity.reloadActivity();
} else {
//myDialog.dismiss();
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
int idErrorRes = getResources().getIdentifier(errorMsg, "string", getPackageName());
String strErrorRes = getString(idErrorRes);
Log.d("NINJA", "ErrorePhP: " + strErrorRes);
//POPUP ERRORE
/*new MaterialDialog.Builder(QueryUtils.this)
.title(getResources().getString(R.string.strDialogAttention_title))
.titleColor(getResources().getColor(R.color.colorAccentDark))
.content(strErrorRes)
.positiveText(R.string.strDialogBtnPositive)
.contentGravity(GravityEnum.CENTER)
.positiveColor(getResources().getColor(R.color.colorAccent))
.icon(getResources().getDrawable(R.drawable.ic_dialog_alert))
.cancelable(false)
.autoDismiss(false)
.onPositive(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
}
})
.show();*/
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("NINJA", "ErroreVolley: " + error);
//myDialog.dismiss();
//POPUP ERRORE
/*new MaterialDialog.Builder(QueryUtils.this)
.title(getResources().getString(R.string.strDialogAttention_title))
.titleColor(getResources().getColor(R.color.colorAccentDark))
.content(getResources().getString(R.string.errorVolley1) + "(" + error + ")")
.positiveText(R.string.strDialogBtnPositive)
.contentGravity(GravityEnum.CENTER)
.positiveColor(getResources().getColor(R.color.colorAccent))
.icon(getResources().getDrawable(R.drawable.ic_dialog_alert))
.cancelable(false)
.autoDismiss(false)
.onPositive(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
}
})
.show();*/
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting parameters to loading url
Map<String, String> params = new HashMap<String, String>();
params.put("userid", UserId);
params.put("id_poll", PollId);
params.put("id_answer", AnswerId);
return params;
}
};
// Adding request to request queue
AppVolleyController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
}
At the end of the update procedure, I call the reloadActivity method in PollActivity, to reload itself. THIS call generate the error below:
LOGCAT
java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference
at android.app.Activity.startActivityForResult(Activity.java:4226)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:68)
at android.app.Activity.startActivityForResult(Activity.java:4183)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:751)
at android.app.Activity.startActivity(Activity.java:4522)
at android.app.Activity.startActivity(Activity.java:4490)
at com.uuaba.uuaba.core.PollActivity.reloadActivity(PollActivity.java:345)
at com.uuaba.uuaba.utils.QueryUtils$1.onResponse(QueryUtils.java:48)
at com.uuaba.uuaba.utils.QueryUtils$1.onResponse(QueryUtils.java:33)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
I'm new in Android programming and I tried different solution found in this great forum, but none of them worked for me.
Please help me
Problem is that you are trying to create a new instance of activity without the use of intent :
PollActivity pollActivity = new PollActivity();
pollActivity.reloadActivity();
You should replace this code with the following lines:
public void onClickChangeActivity() {
Intent intent = new Intent(this, PollActivity.class);
startActivity(intent);
}
But your solution is far away from the ideal solutions available in the market. Restarting the activity whenever there is a change in data because you have to update data can never be a good way to go.
Try considering one of these ways to prevent activity restart
Create a data stream(list of data) and keep on reading that on
activity level.
Create a local broadcast receiver
Do let me know if you need help in above ways.
As a quick fix for the problem you can use this hackish way
Create a callback
interface Result {
void success(ResponseModel model);
void failure(Throwable throw);
}
In QueryUtils
List resultCallbacks = new ArrayList(); public void
addCallback(Result result) { resultCallbacks.add(result); }
create List resultCallbacks and a method addCallback to add the callbacks
In PollsActivity write this
((QueryApplication)getApplicationContext().getApplication()).addCallbacks(this);
and implement the callback.
On receiving any data update your list and do
RVUpdater.notifyDataSetChanged();
Hope this will help.

How can I use Google Forms in Android application?

I want to implement Google Forms in my application. I have to make simple survey type forms as like Google Forms, I searching it from two days but I didn't get any specific document for Google Forms implementing in Android Application.
public class Fragment_Register extends Fragment {
View mainView;
public static final MediaType FORM_DATA_TYPE = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
public static final String URL_FORM = "https://docs.google.com/forms/d/e/1FAIpQLSd7TT0S2pMwvRghAxAwDrJ42sWvI7uhqQBdl1WIyKRXjyWRWQ/formResponse";
public static final String NAME_KEY = "entry.2005620554";
public static final String EMAIL_KEY = "entry.1045781291";
public static final String NUMBER_KEY = "entry.1166974658";
public static final String COLLEGE_KEY="entry.75064397";
public static final String CHECK_KEY="entry.839337160";
public String Categories[]={"Category 1","Category 2","Category 3","Category 4"},category;
public String Events[]={"Event 1","Event 2","Event 3","Event 4"},event;
public String Events2[]={"Event2 1","Event2 2","Event2 3","Event2 4"};
private Context context;
private EditText editName;
private EditText editEmail;
private EditText editPhoneNumber;
private EditText editCollege;
private TextView select;
private CheckBox checkBox1,checkBox2;
private Spinner spinner;
private MultiSelectionSpinner spinner2;
private RelativeLayout layout;
ArrayAdapter<String> adapterCategoryCategory;
ArrayAdapter<String> adapterEventCategory;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mainView=inflater.inflate(R.layout.fragment_fragment__register,container,false);
mainView.setTag("FOUR");
context = mainView.getContext();
Button SubmitButton = (Button)mainView. findViewById(R.id.button_register);
editName = (EditText)mainView. findViewById(R.id.editText_register_name);
editEmail = (EditText)mainView. findViewById(R.id.editText_register_email);
editPhoneNumber = (EditText)mainView. findViewById(R.id.editText_register_phone);
editCollege = (EditText)mainView. findViewById(R.id.editText_register_college);
spinner=(Spinner)mainView.findViewById(R.id.spinner);
spinner2=(MultiSelectionSpinner)mainView.findViewById(R.id.multiSpinner);
select=(TextView)mainView.findViewById(R.id.textViewSelect);
adapterCategoryCategory =new ArrayAdapter<String>(context,android.R.layout.simple_spinner_item, Categories);
adapterCategoryCategory.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapterCategoryCategory);
spinner.setPrompt("Select Category");
adapterEventCategory =new ArrayAdapter<String>(context,android.R.layout.simple_spinner_item, Events);
adapterEventCategory.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner2.setItems(Events);
spinner2.setPrompt("Select Event");
spinner2.setSelection(0);
SubmitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String st=spinner2.getSelectedItemsAsString();
Toast.makeText(context, st, Toast.LENGTH_SHORT).show();
Log.e("Selected",st);
}
});
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
category=adapterView.getItemAtPosition(i).toString();
if(i==0)
{
spinner2.setItems(Events);
}
else if (i==1)
{
spinner2.setItems(Events2);
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
spinner2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
event=adapterView.getItemAtPosition(i).toString();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
return mainView;
}
class PostDataTask extends AsyncTask<String, Void, Boolean> {
ProgressDialog progress;
#Override
protected void onPreExecute() {
progress = new ProgressDialog(context);
progress.setMessage("Please Wait..");
progress.show();
}
#Override
protected Boolean doInBackground(String... contactData) {
Boolean result = true;
String url = contactData[0];
String name = contactData[1];
String email = contactData[2];
String number = contactData[3];
String college = contactData[4];
String postBody = "";
try {
postBody = NAME_KEY + "=" + URLEncoder.encode(name, "UTF-8") +
"&" + EMAIL_KEY + "=" + URLEncoder.encode(email, "UTF-8") +
"&" + NUMBER_KEY + "=" + URLEncoder.encode(number, "UTF-8")+
"&" + COLLEGE_KEY + "=" + URLEncoder.encode(college, "UTF-8");
} catch (UnsupportedEncodingException ex) {
result = false;
}
try {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(FORM_DATA_TYPE, postBody);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
} catch (IOException exception) {
result = false;
}
return result;
}
#Override
protected void onPostExecute(Boolean result) {
progress.cancel();
final AlertDialog.Builder alert=new AlertDialog.Builder(context);
alert.setMessage(result ? "Successfully Registered!" : "There was some error in sending message. Please try again after some time.").setCancelable(false).setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
editName.setText("");
editCollege.setText("");
editEmail.setText("");
editPhoneNumber.setText("");
}
});
AlertDialog alertDialog=alert.create();
alertDialog.show();
}
}
boolean validData()
{ String userName=editName.getText().toString();
String userNumber = editPhoneNumber.getText().toString();
String userEmail = editEmail.getText().toString();
String userCollege=editCollege.getText().toString();
if (userName.length()<3)
{
Toast.makeText(context, "Enter a Valid Name", Toast.LENGTH_SHORT).show();
return false;
}
if (userNumber.length()!=10||userNumber.startsWith("0")||userNumber.startsWith("1")||userNumber.startsWith("2")||userNumber.startsWith("3")||userNumber.startsWith("4")||userNumber.startsWith("5")||userNumber.startsWith("6"))
{
Toast.makeText(context, "Enter a Valid Number", Toast.LENGTH_SHORT).show();
return false;
}
if (userEmail.length()<3)
{
Toast.makeText(context, "Enter a Valid Email Address", Toast.LENGTH_SHORT).show();
return false;
}
if (userCollege.length()<3)
{
Toast.makeText(context, "Enter a Valid College Name", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
}
You can use a web view to render your google form within the application.
If for some reason you prefer not to use a web view, it is also possible to use the 'keys' in a google form(obtained via 'inspect element') to integrate the same with your application. Here is a link detailing the steps.
You can use the following in your onCreate():
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage("Loading...");
queue = Volley.newRequestQueue(getApplicationContext());
submit.setOnClickListener(view -> {
postData(edit_name.getText().toString().trim(), edit_email.getText().toString().trim(),
edit_number.getText().toString().trim(), edit_remarks.getText().toString().trim());l
});
Also create a function in the activity as follows and in my Google Forms I have 4 entries to make which are name, phone, email and remark:
public void postData(final String name, final String email, final String phone, final String remark) {
progressDialog.show();
StringRequest request = new StringRequest(Request.Method.POST, Constants.url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("TAG", "Response: " + response);
if (response.length() > 0) {
Snackbar.make(btn_submit, "Successfully Posted", Snackbar.LENGTH_LONG).show();
finish();
} else {
Snackbar.make(btn_submit, "Try Again", Snackbar.LENGTH_LONG).show();
}
progressDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Snackbar.make(btn_submit, "Error while Posting Data", Snackbar.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put(Constants.nameField, name);
params.put(Constants.emailField, email);
params.put(Constants.phoneField,"+91"+phone);
params.put(Constants.remarkField, remark);
return params;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(
50000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);
}
Create a Java class Constants where you enter the url and id of the entries in forms:
public class Constants {
// Google Forms URL .. replace with yours
public static final String url = "https://docs.google.com/forms/d/e/1FAIpQLSf65J3RmZS6QBg_TrsZZFx9s0l6109Q4E6PvUjuZ9go6D9l2g/formResponse";
// Google Form's Column ID
public static final String nameField = "entry.2006520554";
public static final String phoneField = "entry.1196974658";
public static final String emailField = "entry.1054781291";
public static final String remarkField = "entry.839339060"; }
Entry ids can be found by inspecting your Google Forms. For more details refer to the this link.

List ImageView repeating same image when shared

I have a listView that is supposed to accept a shared message and image where the image is placed within the ImageView. This feature works for just the first message, but once an image is shared, each message received after that initial one becomes a copy of that same image even though the blank image placeholder was already set, which is just a one pixel black png:
holder.sharedSpecial.setImageResource(R.drawable.image_share_empty_holder);
An example is below:
The green textbox is the recipient. They have recieved a shared image from the yellow textbox. The yellow textbox then simply sends a normal message and I have set another image as a placeholder for normal messages: holder.sharedSpecial.setImageResource(R.drawable.image_share_empty_holder);
The same previously shared image takes precedence. I have used notifyDataSetChanged() so as to allow for the updating the adapter so that it would recognize not to use the same image, but to no avail.
How can I reformulate this class so that the image shared is only displayed with the proper message and not copied into each subsequent message?
The ArrayAdapter class:
public class DiscussArrayAdapter extends ArrayAdapter<OneComment> {
class ViewHolder {
TextView countryName;
ImageView sharedSpecial;
LinearLayout wrapper;
}
private TextView countryName;
private ImageView sharedSpecial;
private MapView locationMap;
private GoogleMap map;
private List<OneComment> countries = new ArrayList<OneComment>();
private LinearLayout wrapper;
private JSONObject resultObject;
private JSONObject imageObject;
String getSharedSpecialURL = null;
String getSharedSpecialWithLocationURL = null;
String specialsActionURL = "http://" + Global.getIpAddress()
+ ":3000/getSharedSpecial/";
String specialsLocationActionURL = "http://" + Global.getIpAddress()
+ ":3000/getSharedSpecialWithLocation/";
String JSON = ".json";
#Override
public void add(OneComment object) {
countries.add(object);
super.add(object);
}
public DiscussArrayAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
public int getCount() {
return this.countries.size();
}
private OneComment comment = null;
public OneComment getItem(int index) {
return this.countries.get(index);
}
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.message_list_item, parent, false);
holder = new ViewHolder();
holder.wrapper = (LinearLayout) row.findViewById(R.id.wrapper);
holder.countryName = (TextView) row.findViewById(R.id.comment);
holder.sharedSpecial = (ImageView) row.findViewById(R.id.sharedSpecial);
// Store the ViewHolder as a tag.
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
Log.v("COMMENTING","Comment is " + countries.get(position).comment);
//OneComment comment = getItem(position);
holder.countryName.setText(countries.get(position).comment);
// Initiating Volley
final RequestQueue requestQueue = VolleySingleton.getsInstance().getRequestQueue();
// Check if message has campaign or campaign/location attached
if (countries.get(position).campaign_id == "0" && countries.get(position).location_id == "0") {
holder.sharedSpecial.setImageResource(R.drawable.image_share_empty_holder);
Log.v("TESTING", "It is working");
} else if (countries.get(position).campaign_id != "0" && countries.get(position).location_id != "0") {
// If both were shared
getSharedSpecialWithLocationURL = specialsLocationActionURL + countries.get(position).campaign_id + "/" + countries.get(position).location_id + JSON;
// Test Campaign id = 41
// Location id = 104
// GET JSON data and parse
JsonObjectRequest getCampaignLocationData = new JsonObjectRequest(Request.Method.GET, getSharedSpecialWithLocationURL, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// Parse the JSON:
try {
resultObject = response.getJSONObject("shared");
} catch (JSONException e) {
e.printStackTrace();
}
// Get and set image
Picasso.with(getContext()).load("http://" + Global.getIpAddress() + ":3000" + adImageURL).into(holder.sharedSpecial);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", error.toString());
}
}
);
requestQueue.add(getCampaignLocationData);
} else if (countries.get(position).campaign_id != "0" && countries.get(position).location_id == "0") {
// Just the campaign is shared
getSharedSpecialURL = specialsActionURL + countries.get(position).campaign_id + JSON;
// Test Campaign id = 41
// GET JSON data and parse
JsonObjectRequest getCampaignData = new JsonObjectRequest(Request.Method.GET, getSharedSpecialURL, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// Parse the JSON:
try {
resultObject = response.getJSONObject("shared");
} catch (JSONException e) {
e.printStackTrace();
}
// Get and set image
Picasso.with(getContext()).load("http://" + Global.getIpAddress() + ":3000" + adImageURL).into(holder.sharedSpecial);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", error.toString());
}
}
);
requestQueue.add(getCampaignData);
// Location set to empty
}
// If left is true, then yellow, if not then set to green bubble
holder.countryName.setBackgroundResource(countries.get(position).left ? R.drawable.bubble_yellow : R.drawable.bubble_green);
holder.wrapper.setGravity(countries.get(position).left ? Gravity.LEFT : Gravity.RIGHT);
return row;
}
}
The messaging class that sends normal messages only but can receive image messages and set to the adapter:
public class GroupMessaging extends Activity {
private static final int MESSAGE_CANNOT_BE_SENT = 0;
public String username;
public String groupname;
private Button sendMessageButton;
private Manager imService;
private InfoOfGroup group = new InfoOfGroup();
private InfoOfGroupMessage groupMsg = new InfoOfGroupMessage();
private StorageManipulater localstoragehandler;
private Cursor dbCursor;
private com.example.feastapp.ChatBoxUi.DiscussArrayAdapter adapter;
private ListView lv;
private EditText editText1;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
imService = ((MessagingService.IMBinder) service).getService();
}
public void onServiceDisconnected(ComponentName className) {
imService = null;
Toast.makeText(GroupMessaging.this, R.string.local_service_stopped,
Toast.LENGTH_SHORT).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.message_activity);
lv = (ListView) findViewById(R.id.listView1);
adapter = new DiscussArrayAdapter(getApplicationContext(), R.layout.message_list_item);
lv.setAdapter(adapter);
editText1 = (EditText) findViewById(R.id.editText1);
sendMessageButton = (Button) findViewById(R.id.sendMessageButton);
Bundle extras = this.getIntent().getExtras();
group.userName = extras.getString(InfoOfGroupMessage.FROM_USER);
group.groupName = extras.getString(InfoOfGroup.GROUPNAME);
group.groupId = extras.getString(InfoOfGroup.GROUPID);
String msg = extras.getString(InfoOfGroupMessage.GROUP_MESSAGE_TEXT);
setTitle("Group: " + group.groupName);
// Retrieve the information
localstoragehandler = new StorageManipulater(this);
dbCursor = localstoragehandler.groupGet(group.groupName);
if (dbCursor.getCount() > 0) {
// Probably where the magic happens, and keeps pulling the same
// thing
int noOfScorer = 0;
dbCursor.moveToFirst();
while ((!dbCursor.isAfterLast())
&& noOfScorer < dbCursor.getCount()) {
noOfScorer++;
}
}
localstoragehandler.close();
if (msg != null) {
// Then friends username and message, not equal to null, recieved
adapter.add(new OneComment(true, group.groupId + ": " + msg, "0", "0"));
adapter.notifyDataSetChanged();
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.cancel((group.groupId + msg).hashCode());
}
// The send button
sendMessageButton.setOnClickListener(new OnClickListener() {
CharSequence message;
Handler handler = new Handler();
public void onClick(View arg0) {
message = editText1.getText();
if (message.length() > 0) {
// When general texting, the campaign and location will always be "0"
// Only through specials sharing is the user permitted to change the campaign and location to another value
adapter.add(new OneComment(false, imService.getUsername() + ": " + message.toString(), "0", "0"));
adapter.notifyDataSetChanged();
localstoragehandler.groupInsert(imService.getUsername(), group.groupName,
group.groupId, message.toString(), "0", "0");
// as msg sent, will blank out the text box so can write in
// again
editText1.setText("");
Thread thread = new Thread() {
public void run() {
try {
// JUST PUTTING "0" AS A PLACEHOLDER FOR CAMPAIGN AND LOCATION
// IN FUTURE WILL ACTUALLY ALLOW USER TO SHARE CAMPAIGNS
if (imService.sendGroupMessage(group.groupId,
group.groupName, message.toString(), "0", "0") == null) {
handler.post(new Runnable() {
public void run() {
Toast.makeText(
getApplicationContext(),
R.string.message_cannot_be_sent,
Toast.LENGTH_LONG).show();
// showDialog(MESSAGE_CANNOT_BE_SENT);
}
});
}
} catch (UnsupportedEncodingException e) {
Toast.makeText(getApplicationContext(),
R.string.message_cannot_be_sent,
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
};
thread.start();
}
}
});
}
#Override
protected Dialog onCreateDialog(int id) {
int message = -1;
switch (id) {
case MESSAGE_CANNOT_BE_SENT:
message = R.string.message_cannot_be_sent;
break;
}
if (message == -1) {
return null;
} else {
return new AlertDialog.Builder(GroupMessaging.this)
.setMessage(message)
.setPositiveButton(R.string.OK,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
/* User clicked OK so do some stuff */
}
}).create();
}
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(groupMessageReceiver);
unbindService(mConnection);
ControllerOfGroup.setActiveGroup(null);
}
#Override
protected void onResume() {
super.onResume();
bindService(new Intent(GroupMessaging.this, MessagingService.class),
mConnection, Context.BIND_AUTO_CREATE);
IntentFilter i = new IntentFilter();
i.addAction(MessagingService.TAKE_GROUP_MESSAGE);
registerReceiver(groupMessageReceiver, i);
ControllerOfGroup.setActiveGroup(group.groupName);
}
// For receiving messages form other users...
public class GroupMessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extra = intent.getExtras();
//Log.i("GroupMessaging Receiver ", "received group message");
String username = extra.getString(InfoOfGroupMessage.FROM_USER);
String groupRId = extra.getString(InfoOfGroupMessage.TO_GROUP_ID);
String message = extra
.getString(InfoOfGroupMessage.GROUP_MESSAGE_TEXT);
// NEED TO PLACE INTO THE MESSAGE VIEW!!
String received_campaign_id = extra.getString(InfoOfGroupMessage.CAMPAIGN_SHARED);
String received_location_id = extra.getString(InfoOfGroupMessage.LOCATION_SHARED);
// NEED TO INTEGRATE THIS INTO LOGIC ABOVE, SO IT MAKES SENSE
if (username != null && message != null) {
if (group.groupId.equals(groupRId)) {
adapter.add(new OneComment(true, username + ": " + message, received_campaign_id, received_location_id));
localstoragehandler
.groupInsert(username, groupname, groupRId, message, received_campaign_id, received_location_id);
Toast.makeText(getApplicationContext(), "received_campaign: " + received_campaign_id +
" received_location:" + received_location_id, Toast.LENGTH_LONG).show();
received_campaign_id = "0";
received_location_id = "0";
} else {
if (message.length() > 15) {
message = message.substring(0, 15);
}
Toast.makeText(GroupMessaging.this,
username + " says '" + message + "'",
Toast.LENGTH_SHORT).show();
}
}
}
}
;
// Build receiver object to accept messages
public GroupMessageReceiver groupMessageReceiver = new GroupMessageReceiver();
#Override
protected void onDestroy() {
super.onDestroy();
if (localstoragehandler != null) {
localstoragehandler.close();
}
if (dbCursor != null) {
dbCursor.close();
}
}
}
I have gone through your code and this is common problem with listview that images starts repeating itself. In your case I think you have assigned image to Imageview every if and else if condition but if none of the condition satisfy it uses the previous image.
I would suggest to debug the getview method and put break points on the setImageResource. I use volley for these image loading and it has a method called defaultImage so that if no url is there the image is going to get the default one. So add that default case and see if it works.
If any of the above point is not clear feel free to comment.

android: How to wait for listener to complete before continuing?

I'm using the socialAuth plugin to connect a user to linkdin within my app. I have the connection set up correctly and retrieves data. However, I'm unsure how I can get my main activity to wait until the socialAuthListeners have fired and finished. I know a little about threading but I haven't used it with listeners before. Here's my code:
public class LinkdinAuth {
private static final String TAG = "TEST";
// SocialAuth Components
SocialAuthAdapter adapter;
ProgressDialog mDialog;
private Context context;
private boolean loggedIn = false;
private Bundle LinkdinData;
public LinkdinAuth(Context C){
this.context = C;
LinkdinData = new Bundle();
adapter = new SocialAuthAdapter(new ResponseListener());
}
public void adapterAuthorize(View v){
adapter.authorize(v.getContext(), Provider.LINKEDIN);
}
private final class ResponseListener implements DialogListener
{
public void onComplete(Bundle values) {
String providerName = values.getString(SocialAuthAdapter.PROVIDER);
Log.d("Main", "providername = " + providerName);
mDialog = new ProgressDialog(context);
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mDialog.setMessage("Loading...");
//Get profile information
adapter.getUserProfileAsync(new ProfileDataListener());
// get Job and Education information
mDialog.show();
adapter.getCareerAsync(new CareerListener());
loggedIn = true;
Log.d("Main", "LOGGED IN = " + loggedIn );
Toast.makeText(context, providerName + " connected", Toast.LENGTH_SHORT).show();
}
#Override
public void onBack() {
Log.d("Main", "Dialog Closed by pressing Back Key");
}
#Override
public void onCancel() {
Log.d("Main", "Cancelled");
}
#Override
public void onError(SocialAuthError e) {
Log.d("Main", "Error");
e.printStackTrace();
}
}
// To receive the profile response after authentication
private final class ProfileDataListener implements SocialAuthListener<Profile> {
#Override
public void onExecute(String provider, Profile t) {
Log.d("Sign Up", "Receiving Data");
mDialog.dismiss();
Profile profileMap = t;
LinkdinData.putString("Validated ID", profileMap.getValidatedId() );
LinkdinData.putString("First Name", profileMap.getFirstName());
LinkdinData.putString("Last Name", profileMap.getLastName());
LinkdinData.putString("Email", profileMap.getEmail());
LinkdinData.putString("Country", profileMap.getCountry());
LinkdinData.putString("Language", profileMap.getLanguage());
LinkdinData.putString("Location", profileMap.getLocation());
LinkdinData.putString("Profile Image URL", profileMap.getProfileImageURL());
}
#Override
public void onError(SocialAuthError arg0) {
// TODO Auto-generated method stub
}
}
private final class CareerListener implements SocialAuthListener<Career> {
#Override
public void onExecute(String provider, Career t) {
Log.d("Custom-UI", "Receiving Data");
mDialog.dismiss();
Career careerMap = t;
//get education
Log.d("Main", "Education:");
if(careerMap.getEducations() != null){
for(Education E: careerMap.getEducations()){
Log.d("Main", "School = " +E.getSchoolName() );
Log.d("Main", "Major = " + E.getFieldOfStudy() );
Log.d("Main", "Degree = " + E.getDegree() );
Log.d("Main", "Start Date = " + E.getStartDate() );
Log.d("Main", "End Date = " + E.getEndDate() );
}
}
Log.d("SignUp", "Career");
if(careerMap.getPositions() != null){
for(Position P: careerMap.getPositions()){
LinkdinData.putString("Company Name", P.getCompanyName() );
LinkdinData.putString("Job Title", P.getTitle() );
Log.d("Main", "Industry = " + P.getIndustry() );
Log.d("Main", "Start Date = " + P.getStartDate() );
Log.d("Main", "End Date = " + P.getEndDate() );
}
}
}
#Override
public void onError(SocialAuthError e) {
}
}
public boolean isLoggedIn(){
return loggedIn;
}
public Bundle getLinkdinData(){
return LinkdinData;
}
So, as you can see. I have 2 listeners that get data after authorization goes through. And my main activity makes creates an instance, calls the adapterAuthroizeMethod and then if the user logs in a flag is set. Then getLinkedData is called. However I would like it to wait until I know the listeners have fired before calling getlinkdinData. Here's what my Main Activity does after a button press:
L.adapterAuthorize(v);
loggedInWithLinkdin = L.isLoggedIn();
Bundle B = L.getLinkdinData();
Intent i = new Intent(getBaseContext(), UserRegistration.class);
i.putExtra("linkdin bundle", B);
//startActivity(i);
Any ideas?
thanks
Well, not a recommend solution but more of a hack.
Here is what you can do.
Wrap the aync call around this construct :
AtomicBoolean done = new AtomicBoolean(false);
Global ans; // the return value holder
try{
result = someAsyncCall(query, new Thread()); // this new thread is for listener callback
result.setResultListener(result -> {
// do something with result.
ans = result.getAns() ; // set global ans
done.set(true);
synchronized (done) {
done.notifyAll(); // notify the main thread which is waiting
}
});
}
catch (Exception e ) {
Log(e);
}
synchronized (done) {
while (done.get() == false) {
done.wait(); // wait here until the listener fires
}
}
return ans; // return global ans

Categories

Resources