Android Asyntask API deprecated - android

Been looking on the internet how to check the current app version of the application and the version available on Play Store. But it was using Asynctask that was deprecated already and Ive been looking alternative way aside from Asynctask been searching on the internet but I couldnt figure out how to do it correctly. Please check the code below:
private class GetLatestVersion extends AsyncTask<String, String, String> {
private String latestVersion;
private ProgressDialog progressDialog;
private boolean manualCheck;
GetLatestVersion(boolean manualCheck) {
this.manualCheck = manualCheck;
}
String currentVersion = getCurrentVersion();
//If the versions are not the same
if(!currentVersion.equals(latestVersion)&&latestVersion!=null){
final Dialog dialog = new Dialog(activity);
dialog.setContentView(R.layout.custom_warning_dialog);
dialog.setCancelable(false);
Button tryAgain = dialog.findViewById(R.id.bt_positive);
Button settings = dialog.findViewById(R.id.bt_negative);
tryAgain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id="+activity.getPackageName())));
dialog.dismiss();
}
});
settings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
activity.finish();
}
});
dialog.show();
}else {
if (manualCheck) {
Toast.makeText(activity, "No Update Available", Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected String doInBackground(String... params) {
try {
//It retrieves the latest version by scraping the content of current version from play store at runtime
latestVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + activity.getPackageName() + "&hl=en")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select(".hAyfc .htlgb")
.get(7)
.ownText();
return latestVersion;
} catch (Exception e) {
return latestVersion;
}
}
}

Here's how you can basically convert asyncTask to coroutine on kotlin
private suspend fun GetLatestVersion(String,String,String) {
withContext(Dispatcher.Default)
{
// you just have to refactor all your code inside doInBaakground inside this withContext
}
//then if you want to update the UI
withContext(Dispatchers.Main)
{
//return code for your task
}
}
See this link . For further information.

Thanks Ginxx, but I used executer instead of coroutine since I am only a beginner but it might help others who the same as me.
Check my update codes below:
public void CheckLatestAppVersionFromPlayStore() {
final String[] latestAppVersionFromPlayStore = new String[1];
ExecutorService executor = Executors.newSingleThreadExecutor();
final Handler handler = new Handler(Looper.getMainLooper());
executor.execute(new Runnable() {
#Override
public void run() {
try {
//It retrieves the latest version by scraping the content of current version from play store at runtime
latestAppVersionFromPlayStore[0] = Jsoup.connect("https://play.google.com/store/apps/details?id=" + activityWeakReference.get().getPackageName() + "&hl=it")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select(".hAyfc .htlgb")
.get(7)
.ownText();
} catch (Exception e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
final String installedAppVersion = currentVersionName;
//If the versions are not the same
if (!installedAppVersion.equals(latestAppVersionFromPlayStore[0]))
if (latestAppVersionFromPlayStore[0] != null) {
final Dialog dialog = new Dialog(activityWeakReference.get());
dialog.setContentView(R.layout.custom_warning_dialog);
dialog.setCancelable(false);
Button tryAgain = dialog.findViewById(R.id.bt_positive);
Button settings = dialog.findViewById(R.id.bt_negative);
tryAgain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
activityWeakReference.get().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + activityWeakReference.get().getPackageName())));
}
});
settings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
activityWeakReference.get().finish();
}
});
// to avoid the bad token exception
if ((activityWeakReference.get() != null) && (!activityWeakReference.get().isFinishing()) && (!activityWeakReference.get().isDestroyed()))
dialog.show();
}
}
});
}
});
}
For further information please click this link.

Related

Unable to Get latest version of play store build due to updated design of Play store

Following code used:
public class ForceUpdateAsync extends AsyncTask<String, String,
JSONObject> {
VersionListener mWsCallerVersionListener;
private String latestVersion;
private String currentVersion;
private Context context;
public ForceUpdateAsync(String currentVersion, Context context, VersionListener callback) {
this.currentVersion = currentVersion;
this.context = context;
mWsCallerVersionListener = callback;
}
#Override
protected JSONObject doInBackground(String... params) {
try {
latestVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" +
context.getPackageName() + "&hl=en")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select("div.hAyfc:nth-child(4) > span:nth-child(2) > div:nth-child(1) > span:nth-child(1)")
.first()
.ownText();
Log.e("latestversion", "---" + latestVersion);
} catch (Exception e) {
e.printStackTrace();
mWsCallerVersionListener.onGetResponse(false);
}
return new JSONObject();
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
if (latestVersion != null) {
if (Float.parseFloat(currentVersion)<Float.parseFloat(latestVersion)) {
mWsCallerVersionListener.onGetResponse(true);
} else {
mWsCallerVersionListener.onGetResponse(false);
}
} else {
mWsCallerVersionListener.onGetResponse(false);
}
super.onPostExecute(jsonObject);
}
}
Getting following exception:
Attempt to invoke virtual method 'java.lang.String org.jsoup.nodes.Element.ownText()' on a null object reference
my assumption is that issue occurred due to updated html of play store. how I can get latest version of Play-store build?

Android force update

I am getting crash in one of my projects. This issue is in my force update code.
> Caused by java.lang.NullPointerException: Attempt to invoke virtual
> method 'java.lang.String org.jsoup.nodes.Element.ownText()' on a null
> object reference
> at com.****.android.****.activities.ForceUpdate.doInBackground(ForceUpdate.java:42)
> at com.****.android.****.activities.ForceUpdate.doInBackground(ForceUpdate.java:23)
> at android.os.AsyncTask$2.call(AsyncTask.java:295)
> at java.util.concurrent.FutureTask.run(FutureTask.java:237)
> at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
> at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
> at java.lang.Thread.run(Thread.java:818)
my code is something like this
public class ForceUpdate extends AsyncTask<String,String,JSONObject>
{
private String latestVersion;
private String currentVersion;
private Context context;
public ForceUpdate(String currentVersion, Context context){
this.currentVersion = currentVersion;
this.context = context;
}
#Override
protected JSONObject doInBackground(String... params) {
try {
latestVersion = Jsoup.connect("https://play.google.com/store/apps/details?id="+context.getPackageName()+"&hl=en")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select("div[itemprop=softwareVersion]")
.first()
.ownText();
} catch (IOException e) {
e.printStackTrace();
}
return new JSONObject();
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
if(latestVersion!=null){
if(!currentVersion.equalsIgnoreCase(latestVersion)){
// Toast.makeText(context,"update is available.",Toast.LENGTH_LONG).show();
if(!(context instanceof LoginActivity)) {
if(!((Activity)context).isFinishing()){
showForceUpdateDialog();
}
}
}
}
super.onPostExecute(jsonObject);
}
public void showForceUpdateDialog(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(new ContextThemeWrapper(context,
R.style.Theme_AppCompat_Dialog));
alertDialogBuilder.setTitle(context.getString(R.string.youAreNotUpdatedTitle));
alertDialogBuilder.setMessage(context.getString(R.string.youAreNotUpdatedMessage) + " " + latestVersion + context.getString(R.string.youAreNotUpdatedMessage1));
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton(R.string.updates, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName())));
dialog.dismiss();
}
});
alertDialogBuilder.show();
}}
We are also using Jsoup to get latest app version. For us it works fine. Below is my code -
#Override
protected String doInBackground(Void... voids) {
try {
latestVersion = Jsoup.connect(context.getString(R.string.play_store_url)
+ BuildConfig.APPLICATION_ID)
.timeout(TIMEOUT)
.referrer(context.getString(R.string.google))
.get()
.select(context.getString(R.string.css_parser))
.first()
.ownText();
} catch (Exception e) {
return newVersion;
}
}
Only difference is, userAgent. Try removing it.

How to login by POST method to get access the other APIs from Server Android

In my app I want to to implement a login functionality to get access to server for getting all the necessary API colection. The login request will send by POST method. For login, email address is the mandatory field and password is optional. If I authenticate with the email address, I am able to get all the api colection from server like "/api/users", "api/image". Also the app will redirect to next page. I have tried with the following code to authenticate from server by POSt method. But nothing happen with code. Neither I get any respnse from server nor I redirect to next page. It seems that I have some problem in my code. But I fail to resolve what exactly the problem is.
Here I would like to mention that I do not want to use any library for url connection
Here is my code for login page
public class LoginPage extends AppCompatActivity {
private UserLoginTask mAuthTask = null;
EditText userEmail;
EditText userPassword;
TextView forgotPassword;
View progressView;
View loginFormView;
Button login;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_layout);
//Set up the login form
userEmail=(EditText)findViewById(R.id.email);
userPassword=(EditText)findViewById(R.id.password);
forgotPassword=(TextView)findViewById(R.id.forgot_password);
forgotPassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getBaseContext(),"Redirect to forgot password link",Toast.LENGTH_SHORT).show();
}
});
userPassword.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == R.id.password || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
login=(Button)findViewById(R.id.btn_login);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
attemptLogin();
}
});
loginFormView = findViewById(R.id.login_form);
progressView = findViewById(R.id.login_progress);
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
private void attemptLogin() {
if (mAuthTask != null) {
return;
}
// Reset errors.
userEmail.setError(null);
userPassword.setError(null);
String email = userEmail.getText().toString();
String password = userPassword.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password, if the user entered one.
if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
userPassword.setError(getString(R.string.error_invalid_password));
focusView = userPassword;
cancel = true;
}
else if(TextUtils.isEmpty(password)){
userPassword.setError(getString(R.string.error_field_required));
focusView = userPassword;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(email)) {
userEmail.setError(getString(R.string.error_field_required));
focusView = userEmail;
cancel = true;
} else if (!isEmailValid(email)) {
userEmail.setError(getString(R.string.error_invalid_email));
focusView = userEmail;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mAuthTask = new UserLoginTask(email, password,this);
mAuthTask.execute((Void) null);
}
}
private boolean isEmailValid(String email) {
//TODO: Replace this with other logic
Pattern pattern = Patterns.EMAIL_ADDRESS;
return pattern.matcher(email).matches();
//return true;
}
private boolean isPasswordValid(String password) {
//TODO: Replace this with your own logic
return password.length() > 4;
}
/**
* Shows the progress UI and hides the login form.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
loginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
loginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
loginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
progressView.setVisibility(show ? View.VISIBLE : View.GONE);
progressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
progressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
} else {
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
progressView.setVisibility(show ? View.VISIBLE : View.GONE);
loginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
private interface ProfileQuery {
String[] PROJECTION = {
ContactsContract.CommonDataKinds.Email.ADDRESS,
ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
};
int ADDRESS = 0;
int IS_PRIMARY = 1;
}
/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
private final String mEmail;
private final String mPassword;
Activity instance;
UserLoginTask(String email, String password,Activity instance) {
mEmail = email;
mPassword = password;
this.instance=instance;
}
#Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
JSONObject request = new JSONObject();
try {
request.put("email",mEmail );
} catch (JSONException e) {
e.printStackTrace();
}
try {
request.put("pass",mPassword );
} catch (JSONException e) {
e.printStackTrace();
}
String result = connectWithServer(instance , request,mEmail,mPassword);
if(!TextUtils.isEmpty(result)){
return true;
}else{
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(true);
if (success) {
finish();
Intent loginIntent = new Intent(LoginPage.this, MainOptionPage.class);
startActivity(loginIntent);
} else {
userEmail.setError(getString(R.string.error_incorrect_password));
userPassword.requestFocus();
}
}
#Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
public static String connectWithServer(Activity ctx , JSONObject request, String username, String password) {
String result ="";
try {
//Connect
HttpURLConnection urlConnection = (HttpURLConnection) ((new URL("https://myurl/login")).openConnection());
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type","application/json");
urlConnection.setRequestProperty("Accept","application/json");
urlConnection.setRequestMethod("POST");
urlConnection.connect();
urlConnection.setConnectTimeout(100000);
//Write
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(request.toString());
writer.close();
outputStream.close();
//Read
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
String line;
StringBuilder sb = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
result = sb.toString();
Toast.makeText(ctx,result,Toast.LENGTH_LONG).show();
} catch (UnsupportedEncodingException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}

Can't get the page using Jsoup

There is a problem when it tries to page in a normal java class everything works fine, but if this is done already in the android app, the answer comes "you don't have permission to access" while the user-agent is specified in the android manifest has the permission to use the Internet and all this in a separate thread, can someone faced with this problem
public void onClick(View view)
{
new Thread(new Runnable() {
#Override
public void run()
{
go();
}
}).start();
}
private void go()
{
try {
document = Jsoup.connect("http://issa.beltelecom.by/main.html").userAgent("Chrome 53.0.2785.143").ignoreHttpErrors(true).get();
} catch (IOException e) {
e.printStackTrace();
}
}
It seems to be important to set the Accept header field (note: tested on Android 5.1.1 device).
In general: if the connection is refused using jsoup, inspect the requests (for example using the networks tab in the chrome dev tools/F12) and add missing header fields.
Example Code
String userAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36";
String url = "https://issa.beltelecom.by/main.html";
String acceptValue = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
String host = "issa.beltelecom.by";
document = Jsoup.connect(url).header("Accept",acceptValue).header("Host", host).userAgent(userAgent).get();
You can try this, set your OnClickListener to call the background task.
new MyAsyncTask().execute();
Then perform your task
private class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
protected void onPreExecute() {
super.onPreExecute();
//do anything here
}
protected Boolean doInBackground(Void...param) {
Document document = null;
try {
document = Jsoup.connect(getString(R.string.your_url_string)).get();
} catch (IOException e) {
e.printStackTrace();
}
if (document != null) {
Elements yourElements = document.select("#element_id");
//Do anything here
return true;
}
//Document is null
return false;
}
protected void onPostExecute(Boolean result) {
if(result==true) {
// do this
}
}
}

Linkedin login android SDK access token is not set

I implement LinkedIn Register in to my android app... I use LinkedIn Android SDK:
link and i follow these tutorial: tut
However I stuck in one big problem. I successful get token by method:
LISessionManager.getInstance(getContext()).init(mLoginActivity, buildScope(), new AuthListener() {
And after it i try to make APIHelper request to get profile data:
APIHelper apiHelper = APIHelper.getInstance(getContext());
apiHelper.getRequest(mLoginActivity, topCardUrl, new ApiListener() {
#Override
public void onApiSuccess(ApiResponse s) {
But every time i try to get profile data i get following result:
exceptionMsg: access toke is not set
How can i fix it? I can't understand where is problem. Please help.
Linkedin currently stopped support for Mobile SDK that's why all started getting access token is not set.
For more information https://engineering.linkedin.com/blog/2018/12/developer-program-updates
Alternate to achieve the same in Android by this https://stackoverflow.com/a/22219383
public void login(){
LISessionManager.getInstance(getActivity()).init(getActivity(),
buildScope(), new AuthListener()
{
#Override
public void onAuthSuccess()
{
progress.show();
getUserData();
}
#Override
public void onAuthError(LIAuthError error) {
if(progress.isShowing())
progress.dismiss();
}
}, false);
}
private static Scope buildScope() {
return Scope.build(Scope.R_BASICPROFILE, Scope.R_EMAILADDRESS);
}
String u="https://api.linkedin.com/v1/people/~:(id,first-name,last- name,headline,picture-url,public_profile_url,industry,summary,specialties,picture-urls::(original),positions:(id,title,summary,start-date,end-date,is-current,company:(id,name,type,size,industry,ticker)),educations:(id,school-name,field-of-study,start-date,end-date,degree,activities,notes),associations,interests,num-recommenders,date-of-birth,publications:(id,title,publisher:(name),authors:(id,name),date,url,summary),patents:(id,title,summary,number,status:(id,name),office:(name),inventors:(id,name),date,url),languages:(id,language:(name),proficiency:(level,name)),skills:(id,skill:(name)),certifications:(id,name,authority:(name),number,start-date,end-date),courses:(id,name,number),recommendations-received:(id,recommendation-type,recommendation-text,recommender),honors-awards,three-current-positions,three-past-positions,volunteer)";
public void getUserData()
{
APIHelper apiHelper = APIHelper.getInstance(getActivity());
apiHelper.getRequest(getActivity(), u, new ApiListener() {
#Override
public void onApiSuccess(ApiResponse result) {
try {
//progress.dismiss();
socialData = new SocialLoginBean();
JSONObject json = result.getResponseDataAsJson();
String fname = json.getString("firstName");
String lname = json.getString("lastName");
socialData.setFname(fname);
socialData.setLname(lname);
JSONObject pic = json.getJSONObject("pictureUrls");
JSONArray picarr = pic.getJSONArray("values");
profile_pic = picarr.getString(0);
socialData.setPictureUrl(profile_pic);
JSONObject obj = json.getJSONObject("positions").getJSONArray("values").getJSONObject(0);
JSONObject positions = obj.getJSONObject("company");
String companyDesc="",companyName="",industry="",jobTitle="";
if(obj.has("title"))
jobTitle = obj.getString("title");
if(obj.has("summary"))
companyDesc = obj.getString("summary");
if(positions.has("name"))
companyName = positions.getString("name");
if(json.has("industry"))
industry = json.getString("industry");
String publicProfileUrl = json.getString("publicProfileUrl");
socialData.setProfileUrl(publicProfileUrl);
socialData.setIndustry(industry);
socialData.setCompany(companyName);
socialData.setDesignation(jobTitle);
socialData.setCompanyDescription(companyDesc);
moveTo(socialData);
} catch (Exception e) {
e.printStackTrace();
if(progress.isShowing())
progress.dismiss();
moveTo(socialData);
}
}
#Override
public void onApiError(LIApiError error) {
if(progress.isShowing())
progress.dismiss();
}
});
}

Categories

Resources