I have an array of Urls which I would synchronously.
In fact I'm in an asynctask with a for loop.
I tried using downloadmanager and broadcast receiver without success (the manager use another thread so I can't unregister each time, a leak append).
This is my Asynctask :
package com.ylly.hypred.splashScreen.asynctask;
import android.app.DownloadManager;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Log;
import android.view.WindowManager;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.ylly.hypred.R;
import com.ylly.hypred.api.CallAPI;
import com.ylly.hypred.api.model.MediaAPIModel;
import com.ylly.hypred.api.model.MediaArrayAPIModel;
import com.ylly.hypred.utils.FileManager;
import java.io.File;
import java.util.ArrayList;
/**
* Created by YLLY on 17-11-2015.
*/
public class LoadMedias extends AsyncTask<String, Void, String> {
private MediaArrayAPIModel mediaAPIModels;
private Context context;
private ProgressDialog progressDialog;
private boolean isCallFromUpdate;
private final String TAG = "LoadMedias";
private OnLoadingIsFinished mCallback;
/**
*
*/
public interface OnLoadingIsFinished {
void callProcess();
}
/**
*
* #param context
* #param urls
* #param isCallFromUpdate
*/
public LoadMedias(Context context, MediaArrayAPIModel urls, boolean isCallFromUpdate) {
this.context = context;
this.mediaAPIModels = urls;
progressDialog = new ProgressDialog(context);
this.isCallFromUpdate = isCallFromUpdate;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
if (!isCallFromUpdate)
progressDialog.setTitle(context.getString(R.string.fm_etape_trois_sur_trois));
progressDialog.setMessage(context.getString(R.string.fm_enregistrement));
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(false);
progressDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
progressDialog.setMax(mediaAPIModels.getMediaImagePIModels().size() + mediaAPIModels.getMediaFileAPIModels().size());
progressDialog.setProgress(0);
progressDialog.show();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
mCallback.callProcess();
}
#Override
protected String doInBackground(String... arg0) {
try {
loadMediaImages(mediaAPIModels.getMediaImagePIModels(), progressDialog);
loadMediaFiles(context, mediaAPIModels.getMediaFileAPIModels(), progressDialog);
} catch (Exception e) {
Log.d(TAG, e.toString());
}
return "";
}
/**
*
* #param onLoadingIsFinished
*/
public void setOnLoadingIsFinished(OnLoadingIsFinished onLoadingIsFinished) {
this.mCallback = onLoadingIsFinished;
}
/**
* #param mediaAPIModels
* #param progressDialog
*/
private void loadMediaImages(ArrayList<MediaAPIModel> mediaAPIModels, ProgressDialog progressDialog) {
String type;
for (int i = 0; i < mediaAPIModels.size(); i++) {
type = mediaAPIModels.get(i).getUrl().substring(mediaAPIModels.get(i).getUrl().lastIndexOf("."));
if (type.equals(".png") || type.equals(".jpg") || type.equals(".jpeg")) {
ImageLoader.getInstance().loadImageSync(CallAPI.mBaseUrl + mediaAPIModels.get(i).getUrl());
i++;
progressDialog.setProgress(progressDialog.getProgress() + 1);
}
}
}
/**
* #param context
* #param mediaAPIModels
* #param progressDialog
*/
private void loadMediaFiles(Context context, ArrayList<MediaAPIModel> mediaAPIModels, final ProgressDialog progressDialog) {
{
String name;
String mime;
for (int i = 0; i < mediaAPIModels.size(); i++) {
if (!FileManager.getInstance().getFileFromLocal(context, mediaAPIModels.get(i).getUrl(), false)) {
name = mediaAPIModels.get(i).getUrl().substring(mediaAPIModels.get(i).getUrl().lastIndexOf("/") + 1); //on sépare le nom du fichier du reste de l'url
mime = name.substring(name.lastIndexOf(".")); //on recupere l'extension du fichier
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(CallAPI.mBaseUrl + mediaAPIModels.get(i).getUrl()));
request.setDescription(context.getResources().getString(R.string.downloading) + " name");
request.setTitle(context.getResources().getString(R.string.app_name));
request.setMimeType(mime);
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir("test" + File.separatorChar + "doc", name);
// get download service and enqueue file
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
context.registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
context.unregisterReceiver(this);
Log.d("DOWNLOAD", "unregister");
progressDialog.setProgress(progressDialog.getProgress() + 1);
}
}, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
} else {
i++;
progressDialog.setProgress(progressDialog.getProgress() + 1);
}
}
}
}
}
The cache loading works.
Thanks in advance ;)
Related
I tried to write a "login" App using MVP model. And I use WAMP to build up my server. I'm sure that my php documents have no problem.
Here is the structure of my App:
enter image description here
And here are the files:
User.java
package com.example.android.login.mvp;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.presenter.UserLoginPresenter;
import com.example.android.login.mvp.view.IUserLoginView;
public class UserLoginActivity extends AppCompatActivity implements IUserLoginView
{
private EditText mEtUsername, mEtPassword;
private Button mBtnLogin, mBtnClear;
private ProgressBar mPbLoading;
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_login);
initViews();
}
private void initViews()
{
mEtUsername = (EditText) findViewById(R.id.id_et_username);
mEtPassword = (EditText) findViewById(R.id.id_et_password);
mBtnClear = (Button) findViewById(R.id.id_btn_clear);
mBtnLogin = (Button) findViewById(R.id.id_btn_login);
mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);
mBtnLogin.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.login();
}
});
mBtnClear.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.clear();
}
});
}
#Override
public String getUserName()
{
return mEtUsername.getText().toString();
}
#Override
public String getPassword()
{
return mEtPassword.getText().toString();
}
#Override
public void clearUserName()
{
mEtUsername.setText("");
}
#Override
public void clearPassword()
{
mEtPassword.setText("");
}
#Override
public void showLoading()
{
mPbLoading.setVisibility(View.VISIBLE);
}
#Override
public void hideLoading()
{
mPbLoading.setVisibility(View.GONE);
}
#Override
public void toMainActivity(User user)
{
Toast.makeText(this, user.getUsername() +
" login success , to MainActivity", Toast.LENGTH_SHORT).show();
}
#Override
public void showFailedError()
{
Toast.makeText(this,
"login failed", Toast.LENGTH_SHORT).show();
}
}
IUserBiz.java
package com.example.android.login.mvp.biz;
/**
* Created by zhy on 15/6/19.
*/
public interface IUserBiz
{
public void login(String username, String password, OnLoginListener loginListener);
}
OnLoginListener.java
package com.example.android.login.mvp.biz;
import com.example.android.login.mvp.bean.User;
/**
* Created by zhy on 15/6/19.
*/
public interface OnLoginListener
{
void loginSuccess(User user);
void loginFailed();
}
UserBiz.java
package com.example.android.login.mvp.biz;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
/**
* Created by zhy on 15/6/19.
*/
public class UserBiz extends AppCompatActivity implements IUserBiz
{
private User user;
private OnLoginListener loginListener;
#Override
public void login(final String username, final String password, final OnLoginListener mLoginListener)
{
user = new User();
user.setUsername(username);
user.setPassword(password);
user.setStatus(0);
loginListener = mLoginListener;
LoginAsyncTask task = new LoginAsyncTask();
String test1Url = getString(R.string.server_ip)+"/server/login.php";
task.execute(test1Url);
}
/**
* Update the UI with the given earthquake information.
*/
private void updateUi(User mUser) {
if (mUser.getStatus()==1)
{
loginListener.loginSuccess(user);
} else
{
loginListener.loginFailed();
}
}
private class LoginAsyncTask extends AsyncTask<String, Void, User> {
#Override
protected User doInBackground(String... urls) {
if (urls.length < 1 || urls[0] == null) {
return null;
}
// Perform the HTTP request for earthquake data and process the response.
User mUser = Utils.fetchEarthquakeData(urls[0],user);
return mUser;
}
#Override
protected void onPostExecute(User result) {
if(result==null){
return;
}
updateUi(result);
}
}
}
Utils.java
package com.example.android.login.mvp.biz;
import android.text.TextUtils;
import android.util.Log;
import com.example.android.login.mvp.bean.User;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
/**
* Utility class with methods to help perform the HTTP request and
* parse the response.
*/
public final class Utils {
/** Tag for the log messages */
public static final String LOG_TAG = Utils.class.getSimpleName();
/**
* Query the USGS dataset and return an {#link User} object to represent a single earthquake.
*/
public static User fetchEarthquakeData(String requestUrl, User user) {
// Create URL object
URL url = createUrl(requestUrl);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(url, user);
} catch (IOException e) {
Log.e(LOG_TAG, "Error closing input stream", e);
}
// Extract relevant fields from the JSON response and create an {#link User} object
User earthquake = extractFeatureFromJson(jsonResponse);
// Return the {#link User}
return earthquake;
}
/**
* Returns new URL object from the given string URL.
*/
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error with creating URL ", e);
}
return url;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private static String makeHttpRequest(URL url, User user) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
String params="app_user_name="+user.getUsername()+'&'+"app_password="+user.getPassword();
OutputStream out=urlConnection.getOutputStream();
out.write(params.getBytes());//post提交参数
out.flush();
out.close();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return an {#link User} object by parsing out information
* about the first earthquake from the input earthquakeJSON string.
*/
private static User extractFeatureFromJson(String earthquakeJSON) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(earthquakeJSON)) {
return null;
}
try {
JSONObject baseJsonResponse = new JSONObject(earthquakeJSON);
// If there are results in the features array
if (baseJsonResponse.length() > 0) {
int status = baseJsonResponse.getInt("status");
// Create a new {#link User} object
User user=new User();
user.setStatus(status);
return user;
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
}
return null;
}
}
UserLoginPresenter.java
package com.example.android.login.mvp.presenter;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.biz.IUserBiz;
import com.example.android.login.mvp.biz.OnLoginListener;
import com.example.android.login.mvp.biz.UserBiz;
import com.example.android.login.mvp.view.IUserLoginView;
/**
* Created by zhy on 15/6/19.
*/
public class UserLoginPresenter {
private IUserBiz userBiz;
private IUserLoginView userLoginView;
public UserLoginPresenter(IUserLoginView userLoginView) {
this.userLoginView = userLoginView;
this.userBiz = new UserBiz();
}
public void login() {
userLoginView.showLoading();
userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() {
#Override
public void loginSuccess(final User user) {
userLoginView.toMainActivity(user);
userLoginView.hideLoading();
}
#Override
public void loginFailed() {
userLoginView.showFailedError();
userLoginView.hideLoading();
}
});
}
public void clear() {
userLoginView.clearUserName();
userLoginView.clearPassword();
}
}
IUserLoginView.java
package com.example.android.login.mvp.view;
import com.example.android.login.mvp.bean.User;
/**
* Created by zhy on 15/6/19.
*/
public interface IUserLoginView
{
String getUserName();
String getPassword();
void clearUserName();
void clearPassword();
void showLoading();
void hideLoading();
void toMainActivity(User user);
void showFailedError();
}
UserLoginActivity.java
package com.example.android.login.mvp;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.presenter.UserLoginPresenter;
import com.example.android.login.mvp.view.IUserLoginView;
public class UserLoginActivity extends AppCompatActivity implements IUserLoginView
{
private EditText mEtUsername, mEtPassword;
private Button mBtnLogin, mBtnClear;
private ProgressBar mPbLoading;
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_login);
initViews();
}
private void initViews()
{
mEtUsername = (EditText) findViewById(R.id.id_et_username);
mEtPassword = (EditText) findViewById(R.id.id_et_password);
mBtnClear = (Button) findViewById(R.id.id_btn_clear);
mBtnLogin = (Button) findViewById(R.id.id_btn_login);
mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);
mBtnLogin.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.login();
}
});
mBtnClear.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.clear();
}
});
}
#Override
public String getUserName()
{
return mEtUsername.getText().toString();
}
#Override
public String getPassword()
{
return mEtPassword.getText().toString();
}
#Override
public void clearUserName()
{
mEtUsername.setText("");
}
#Override
public void clearPassword()
{
mEtPassword.setText("");
}
#Override
public void showLoading()
{
mPbLoading.setVisibility(View.VISIBLE);
}
#Override
public void hideLoading()
{
mPbLoading.setVisibility(View.GONE);
}
#Override
public void toMainActivity(User user)
{
Toast.makeText(this, user.getUsername() +
" login success , to MainActivity", Toast.LENGTH_SHORT).show();
}
#Override
public void showFailedError()
{
Toast.makeText(this,
"login failed", Toast.LENGTH_SHORT).show();
}
}
But I got something wrong like this:
enter image description here
I have no idea about it. How to solve it?
the issue is here
this.userBiz = new UserBiz();
UserBiz is an activity so activity gets their context when they are being started with Intent (by OS) but creating an object of an activity will not provide any contenxt hence the null exception at
#Override
public void login(final String username, final String password, final OnLoginListener mLoginListener)
{
user = new User();
user.setUsername(username);
user.setPassword(password);
user.setStatus(0);
loginListener = mLoginListener;
LoginAsyncTask task = new LoginAsyncTask();
String test1Url = getString(R.string.server_ip)+"/server/login.php";
// no context here due to new UserBiz
// getString required context
task.execute(test1Url);
}
Solution : you can use enums or static final constants to avoid context and also would be wise to substitute UserBiz as separate class instead of an activity
I am writing an App that connects to the Fitbit API correctly and pulls back the data I need. I have an Inner class that extends AsyncTask that lets me complete this. So for example, my MainActivity.java opens the Fitbit OAuth2 page and the user logs in. The user is then directed back to the UserActivity.java and their info is displayed.
I now want to add another Activity that pulls back the information for the Activities that they carried out. So, my question is, do I need to add another inner class in my ActivitiesActivity.java or is there some other way to get the data. I know people have used an Interface before but I'm not sure how they work with AsyncTask.
package com.jordan.fitbit_connect;
import android.net.Uri;
import android.os.Bundle;
import android.support.customtabs.CustomTabsIntent;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
String response_type = "token";
String client_id = "22CJH3";
String redirect_uri = "myapplication://login";
String scope = "activity%20nutrition%20heartrate%20location%20nutrition%20profile%20settings%20sleep%20social%20weight";
String url = "https://www.fitbit.com/oauth2/authorize?" + "response_type=" + response_type + "&client_id=" + client_id + "&redirect_uri=" + redirect_uri + "&scope=" + scope;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//
// CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
// customTabsIntent.launchUrl(this, Uri.parse(url));
connectToFitbit();
}
public void connectToFitbit()
{
Button btn = (Button)findViewById(R.id.btnConnect);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
customTabsIntent.launchUrl(getApplicationContext(), Uri.parse(url));
}
});
}
}
package com.jordan.fitbit_connect;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class TestActivity extends AppCompatActivity
{
//String to hold the data sent back by the Intent
String string;
//String to extract the token from 'string' above
private static String token;
//Strings to get the data from the JSON Object
public static String name, avatar, age, weight, height;
TextView username, txtAge, txtWeight, txtHeight, txtBMI;
float bmi;
ImageView imgViewAvatar;
//-------------------------------------- START onNewIntent()------------------------------------
/*
This method returns the URI from the Intent as an encoded String
*/
#Override
protected void onNewIntent(Intent intent)
{
string = intent.getDataString();
}
//-------------------------------------- END onNewIntent()--------------------------------------
//-------------------------------------- START onCreate()---------------------------------------
/*
Default method when the class is created
*/
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
onNewIntent(getIntent());
token = string.substring(string.indexOf("&access_token")+36,308);
Log.i("TAG", "Access Token: "+ token);
Log.i("TAG", "Data String: " + string);
//new JSONTask().execute("https://api.fitbit.com/1.2/user/-/sleep/date/2017-10-26.json");
//new JSONTask().execute("https://api.fitbit.com/1/user/-/activities/steps/date/today/6m.json");
new JSONTask().execute("https://api.fitbit.com/1/user/-/profile.json");
}
//-------------------------------------- END onCreate()-----------------------------------------
//-------------------------------------- START of inner class JSONTask -------------------------
public class JSONTask extends AsyncTask<String,String,String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
username = (TextView)findViewById(R.id.txtUser);
imgViewAvatar = (ImageView)findViewById(R.id.imgViewAvatar);
txtAge = (TextView)findViewById(R.id.txtAge);
txtWeight = (TextView) findViewById(R.id.txtWeight);
txtHeight = (TextView) findViewById(R.id.txtHeight);
txtBMI = (TextView) findViewById(R.id.txtBMI);
}
//-------------------------------------- START doInBackground()-----------------------------
/*
This method is what happens on the background thread when the
app is running. It will
*/
#Override
protected String doInBackground(String... params)
{
HttpURLConnection connection = null;
BufferedReader reader = null;
try
{
URL url = new URL(params[0]);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(false);
connection.addRequestProperty("Authorization", "Bearer " + token);
connection.connect();
InputStream stream = (InputStream)connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while((line = reader.readLine()) !=null)
{
buffer.append(line);
}
return buffer.toString();
} catch (MalformedURLException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.toString();
}
return null;
}
//-------------------------------------- END doInBackground()-------------------------------
//-------------------------------------- START onPostExecute()------------------------------
#Override
protected void onPostExecute(String data)
{
super.onPostExecute(data);
Log.i("TAG", data);
try
{
//GET ALL THE JSON DATA
JSONObject allData = new JSONObject(data);
//GET THE USERNAME
JSONObject userObject = allData.getJSONObject("user");
name = userObject.getString("fullName");
username.append(" "+name);
//GET THE USER'S AVATAR
avatar = userObject.getString("avatar640");
Picasso.get().load(avatar).into(imgViewAvatar);
//GET THE USER'S AGE
age = userObject.getString("age");
txtAge.append(" "+age);
weight = userObject.getString("weight");
txtWeight.append(" "+weight);
float weightFloat = Float.parseFloat(weight);
height = userObject.getString("height");
txtHeight.append(" "+height);
float heightFloat= Float.parseFloat(height)/100;
bmi = (float)(weightFloat/(heightFloat * heightFloat));
if(bmi <= 16)
{
txtBMI.setTextColor(Color.YELLOW);
txtBMI.append(" "+ String.valueOf(bmi) + " - You are severely underweight!");
}
else if(bmi <= 18.5)
{
txtBMI.setTextColor(Color.GRAY);
txtBMI.append(" "+ String.valueOf(bmi) + " - You are underweight!");
}
else if(bmi <= 25)
{
txtBMI.setTextColor(Color.GREEN);
txtBMI.append(" "+ String.valueOf(bmi) + " - Your weight is normal");
}
else if(bmi <= 30)
{
txtBMI.setTextColor(Color.parseColor("#FFA500"));
txtBMI.append(" "+ String.valueOf(bmi) + " - You are overweight!");
}
else
{
txtBMI.setTextColor(Color.RED);
txtBMI.append(" " + String.valueOf(bmi) + " - You are obese!");
}
// for(int i =0; i< userObject.length(); i++) {
//3.DECLARE ANOTHER JSONOBJECT THAT EXTRACTS THE OBECT FROM THE SPECIFIED ARRAY
//JSONObject sleep = sleepArray.getJSONObject(i);
//4.Then use a getString to get the data from the object
//name = userObject.getString("firstName");
// Log.i("TAG",name);
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
//-------------------------------------- END of inner class JSONTask ---------------------------
}
One of the methods using AsynTask in different Activities, creating a callback interface.
Create a callback interface
interface AsyncTaskListener<T> {
public void onComplete(T result);
}
Then in your MainActivity and TestActivity:
public class MainActivity extends AppCompatActivity
implements AsyncTaskListener<String> {
public void onComplete(String result) {
// your staff here
}
}
public class TestActivity extends AppCompatActivity
implements AsyncTaskListener<String> {
public void onComplete(String result) {
// your staff here
}
}
And add to your AsyncTask class:
public class JSONTask extends AsyncTask<String, String, String>
private AsyncTaskListener<String> listener;
public JSONTask (AsyncTaskListener<String> callback) {
this.listener = callback;
}
protected void onPostExecute(String result) {
listener.onComplete(result); // calling onComplate interface
}
Am trying to integrate twitter with my application to share message and image on my twitter wall. But displaying following exception:
05-17 01:06:28.151: D/Twitter Update Error(22720): 401:Authentication credentials (https://dev.twitter.com/pages/auth) were missing or incorrect. Ensure that you have set valid consumer key/secret, access token/secret, and the system clock is in sync.
05-17 01:06:28.151: D/Twitter Update Error(22720): {"request":"\/1.1\/statuses\/update.json","error":"Read-only application cannot POST."}
05-17 01:06:28.161: W/System.err(22720): 401:Authentication credentials (https://dev.twitter.com/pages/auth) were missing or incorrect. Ensure that you have set valid consumer key/secret, access token/secret, and the system clock is in sync.
05-17 01:06:28.161: W/System.err(22720): {"request":"\/1.1\/statuses\/update.json","error":"Read-only application cannot POST."}
05-17 01:06:28.161: W/System.err(22720): Relevant discussions can be found on the Internet at:
05-17 01:06:28.161: W/System.err(22720): http://www.google.co.jp/search?q=2fc5b7cb or
05-17 01:06:28.161: W/System.err(22720): http://www.google.co.jp/search?q=11613e08
05-17 01:06:28.161: W/System.err(22720): TwitterException{exceptionCode=[2fc5b7cb-11613e08], statusCode=401, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=4.0.1}
05-17 01:06:28.161: W/System.err(22720): at twitter4j.HttpClientImpl.handleRequest(HttpClientImpl.java:164)
05-17 01:06:28.161: W/System.err(22720): at twitter4j.HttpClientBase.request(HttpClientBase.java:53)
05-17 01:06:28.161: W/System.err(22720): at twitter4j.HttpClientBase.post(HttpClientBase.java:82)
05-17 01:06:28.166: W/System.err(22720): at twitter4j.TwitterImpl.post(TwitterImpl.java:2004)
05-17 01:06:28.166: W/System.err(22720): at twitter4j.TwitterImpl.updateStatus(TwitterImpl.java:251)
05-17 01:06:28.166: W/System.err(22720): at com.android.twitterapi.Item$updateTwitterStatus.doInBackground(Item.java:64)
05-17 01:06:28.171: W/System.err(22720): at com.android.twitterapi.Item$updateTwitterStatus.doInBackground(Item.java:1)
05-17 01:06:28.171: W/System.err(22720): at android.os.AsyncTask$2.call(AsyncTask.java:288)
05-17 01:06:28.171: W/System.err(22720): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-17 01:06:28.176: W/System.err(22720): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-17 01:06:28.176: W/System.err(22720): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-17 01:06:28.176: W/System.err(22720): at java.lang.Thread.run(Thread.java:841)
Can anyone please help me?
Following is my code:
MainActivity:
package com.android.twitterapi;
import me.grantland.twitter.Twitter;
import me.grantland.twitter.Twitter.DialogListener;
import me.grantland.twitter.TwitterError;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
public static final String CONSUMER_KEY = "fZRZJcNrFbg55dmr4rLVA";
public static final String CONSUMER_SECRET = "Xbxmn2hlT91mzydcmbnGRqOIYg8Ohipd9F8HfQYhHg";
private Twitter mTwitter;
private Button mTwitterButton;
String access_token ;
// Access Token Secret
String access_token_secret ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
mTwitter = new Twitter(CONSUMER_KEY, CONSUMER_SECRET);
mTwitterButton = (Button)findViewById(R.id.twitter_login);
mTwitterButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v.equals(mTwitterButton)) {
mTwitter.authorize(this, new DialogListener() {
#Override
public void onComplete(String accessKey, String accessSecret) {
access_token = accessKey;
access_token_secret = accessSecret;
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Success")
.setMessage("access_key: " + accessKey
+ "\naccess_secret: " + accessSecret)
.setPositiveButton("Ok", null);
AlertDialog alert = builder.create();
alert.show();
new Item(MainActivity.this, accessKey, accessSecret);
}
#Override
public void onCancel() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Canceled")
.setMessage("Twitter Login Canceled")
.setPositiveButton("Ok", null);
AlertDialog alert = builder.create();
alert.show();
}
#Override
public void onError(TwitterError error) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Error")
.setMessage(error.getMessage())
.setPositiveButton("Ok", null);
AlertDialog alert = builder.create();
alert.show();
}
});
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Twitter Auth Callback
mTwitter.authorizeCallback(requestCode, resultCode, data);
}
}
Item.java:
package com.android.twitterapi;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.api.TweetsResources;
import twitter4j.auth.AccessToken;
import twitter4j.conf.ConfigurationBuilder;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
public class Item {
Activity mActivity;
String access_token;
String access_token_secret;
public Item(Activity activity, String key, String secret ) {
mActivity = activity;
access_token = key;
access_token_secret = secret;
new updateTwitterStatus().execute("Om Sri Sri Sri Veerabhadra Swamy");
}
/**
* Function to update status
* */
class updateTwitterStatus extends AsyncTask<String, String, String> {
ProgressDialog pDialog;
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(mActivity);
pDialog.setMessage("Updating to twitter...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting Places JSON
* */
protected String doInBackground(String... args) {
Log.d("Tweet Text", "> " + args[0]);
String status = args[0];
try {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(MainActivity.CONSUMER_KEY);
builder.setOAuthConsumerSecret(MainActivity.CONSUMER_SECRET);
// Access Token
AccessToken accessToken = new AccessToken(access_token, access_token_secret);
Twitter twitter = new TwitterFactory(builder.build()).getInstance(accessToken);
// Update status
twitter4j.Status response = ((TweetsResources) twitter).updateStatus(status);
Log.d("Status", "> " + response.getText());
} catch (TwitterException e) {
// Error in updating status
Log.d("Twitter Update Error", e.getMessage());
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog and show
* the data in UI Always use runOnUiThread(new Runnable()) to update UI
* from background thread, otherwise you will get error
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// // updating UI from Background Thread
// runOnUiThread(new Runnable() {
// #Override
// public void run() {
Toast.makeText(mActivity,
"Status tweeted successfully", Toast.LENGTH_SHORT)
.show();
// Clearing EditText field
//// txtUpdate.setText("");
// }
// });
}
}
}
Twitter.java:
package me.grantland.twitter;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
/**
* #author Grantland Chew
*/
public class Twitter {
public static final String TAG = "me.grantland.twitter";
public static final boolean DEBUG = false;
public static final String REQUEST_TOKEN = "https://twitter.com/oauth/request_token";
public static final String ACCESS_TOKEN = "https://twitter.com/oauth/access_token";
public static final String AUTHORIZE = "https://twitter.com/oauth/authorize";
public static final String DENIED = "denied";
public static final String CALLBACK_SCHEME = "gc";
public static final String CALLBACK_URI = CALLBACK_SCHEME + "://twitt";
public static final String EXTRA_ERROR = "error";
public static final String EXTRA_CONSUMER = "consumer";
public static final String EXTRA_AUTHORIZE_PARAMS = "params";
public static final String EXTRA_ACCESS_KEY = "access_key";
public static final String EXTRA_ACCESS_SECRET = "access_secret";
// Used as default activityCode by authorize(). See authorize() below.
public static final int DEFAULT_AUTH_ACTIVITY_CODE = 4242;
private OAuthConsumer mConsumer = null;
private int mRequestCode;
private DialogListener mListener = null;
public Twitter(String consumerKey, String consumerSecret) {
if (consumerKey == null || consumerSecret == null) {
throw new IllegalArgumentException(
"You must specify your consumer key and secret when instantiating " +
"a Twitter object. See README for details.");
}
mConsumer = new CommonsHttpOAuthConsumer(consumerKey, consumerSecret);
}
/**
* Short authorize method that uses default settings.
*
* Starts either an activity or dialog that a user will use to enter their credentials
* to authorize your application with Twitter.
*
* #param activity
* The Activity to display the authorization window on.
* #param listener
* The callback for Twitter authentication responses.
* #return
*/
public boolean authorize(Activity activity, final DialogListener listener) {
return authorize(activity, false, null, DEFAULT_AUTH_ACTIVITY_CODE, listener);
}
/**
* Short authorize method that uses the default activityCode.
*
* Starts either an activity or dialog that a user will use to enter their credentials
* to authorize your application with Twitter.
*
* #param activity
* The Activity to display the authorization window on.
* #param forceLogin
* Forces the user to enter their credentials to ensure the correct users account
* is authorized.
* #param screenName
* Prefills the username input box of the OAuth login screen with the given value.
* #param listener
* The callback for Twitter authentication responses.
* #return
*/
public boolean authorize(Activity activity, boolean forceLogin, String screenName, DialogListener listener) {
return authorize(activity, forceLogin, screenName, DEFAULT_AUTH_ACTIVITY_CODE, listener);
}
/**
* Full authorize method.
*
* Starts either an activity or dialog that a user will use to enter their credentials
* to authorize your application with Twitter.
*
* #param activity
* The Activity to display the authorization window on.
* #param forceLogin
* Forces the user to enter their credentials to ensure the correct users account
* is authorized.
* #param screenName
* Prefills the username input box of the OAuth login screen with the given value.
* #param activityCode
* The requestCode used in Activity#onActivityResult. Can be changed if the default
* conflicts with another Activity in your application.
* #param listener
* The callback for Twitter authentication responses.
* #return
*/
public boolean authorize(Activity activity, boolean forceLogin, String screenName, int activityCode, DialogListener listener) {
// Optional params
String authorizeParams = "";
if (forceLogin) {
authorizeParams += "?force_login=" + forceLogin;
}
if (screenName != null) {
authorizeParams += (authorizeParams.length() == 0 ? "&" : "?") + "screen_name=" + screenName;
}
if (DEBUG) Log.d(TAG, "authorize params: " + authorizeParams);
// We could check if the activity exists in the manifest and fallback on
// the dialog, but if a user wants to use the dialog they can.
if (activityCode > 0) {
startTwitterActivity(activity, authorizeParams, activityCode, listener);
} else {
startTwitterDialog(activity, authorizeParams, listener);
}
return true;
}
private boolean startTwitterActivity(Activity activity, String authorizeParams, int activityCode, DialogListener listener) {
mRequestCode = activityCode;
mListener = listener;
Intent intent = new Intent(activity, TwitterActivity.class);
intent.putExtra(EXTRA_CONSUMER, mConsumer);
intent.putExtra(EXTRA_AUTHORIZE_PARAMS, authorizeParams);
activity.startActivityForResult(intent, DEFAULT_AUTH_ACTIVITY_CODE);
return true;
}
private boolean startTwitterDialog(Activity activity, String authorizeParams, final DialogListener listener) {
TwitterDialog dialog = new TwitterDialog(activity, mConsumer, authorizeParams, new DialogListener() {
#Override
public void onComplete(String token, String secret) {
if (DEBUG) Log.d(TAG, "access_key: " + token);
if (DEBUG) Log.d(TAG, "access_secret: " + secret);
mConsumer.setTokenWithSecret(token, secret);
listener.onComplete(token, token);
}
#Override
public void onError(TwitterError error) {
listener.onError(error);
}
#Override
public void onCancel() {
listener.onCancel();
}
});
dialog.show();
return true;
}
/**
* Callback for Twitter authorize. Should be called in any Activity that calls
* Twitter#authorize.
*
* #param requestCode
* The integer request code originally supplied to
* startActivityForResult(), allowing you to identify who this
* result came from.
* #param resultCode
* The integer result code returned by the child activity
* through its setResult().
* #param data
* An Intent, which can return result data to the caller
* (various data can be attached to Intent "extras").
*/
public void authorizeCallback(int requestCode, int resultCode, Intent data) {
if (mRequestCode != requestCode) {
return;
}
String accessKey, accessSecret;
if (Activity.RESULT_OK == resultCode) {
String error = data.getStringExtra(EXTRA_ERROR);
if (error != null) {
mListener.onError(new TwitterError(error));
} else {
accessKey = data.getStringExtra(EXTRA_ACCESS_KEY);
accessSecret = data.getStringExtra(EXTRA_ACCESS_SECRET);
if (DEBUG) Log.d(TAG, "access_key: " + accessKey);
if (DEBUG) Log.d(TAG, "access_secret: " + accessSecret);
mConsumer.setTokenWithSecret(accessKey, accessSecret);
if (mListener != null) {
mListener.onComplete(accessKey, accessSecret);
return;
}
}
} else if (Activity.RESULT_CANCELED == resultCode) {
if (mListener != null) {
mListener.onCancel();
}
}
}
//==============================================================================================
// Properties
//==============================================================================================
/**
* #return boolean - whether this object has an non-expired session token.
*/
public boolean isSessionValid() {
return mConsumer != null && (getAccessToken() != null && getAccessTokenSecret() != null);
}
/**
* #return String - the consumer_key.
*/
public String getConsumerKey() {
return mConsumer.getConsumerKey();
}
/**
* #return String - the consumer_secret.
*/
public String getConsumerSecret() {
return mConsumer.getConsumerSecret();
}
/**
* Sets the consumer_key and consumer_secret.
* #param consumerKey
* #param consumerSecret
*/
public void setConsumerKeyAndSecret(String consumerKey, String consumerSecret) {
mConsumer = new CommonsHttpOAuthConsumer(consumerKey, consumerSecret);
}
/**
* #return String - the access_token.
*/
public String getAccessToken() {
return mConsumer.getToken();
}
/**
* #return String - the access_token_secret.
*/
public String getAccessTokenSecret() {
return mConsumer.getTokenSecret();
}
/**
* Sets the access_token and access_token_secret.
* #param token
* #param secret
*/
public void setTokenWithSecret(String token, String secret) {
mConsumer.setTokenWithSecret(token, secret);
}
/**
* Callback interface for dialog requests.
*/
public static interface DialogListener {
/**
* Called when a dialog completes.
*
* Executed by the thread that initiated the dialog.
*
* #param values
* Key-value string pairs extracted from the response.
*/
public void onComplete(String accessKey, String accessSecret);
/**
* Called when a dialog has an error.
*
* Executed by the thread that initiated the dialog.
*/
public void onError(TwitterError error);
/**
* Called when a dialog is canceled by the user.
*
* Executed by the thread that initiated the dialog.
*/
public void onCancel();
}
}
TwitterActivity.java:
package me.grantland.twitter;
import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;
import oauth.signpost.exception.OAuthException;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.android.twitterapi.R;
public class TwitterActivity extends Activity {
private static final String TAG = Twitter.TAG;
private static final boolean DEBUG = Twitter.DEBUG;
private static final int RETRIEVE_REQUEST_TOKEN = 1;
private static final int RETRIEVE_ACCESS_TOKEN = 2;
private static final String KEY_URL = "url";
private H mMainThreadHandler;
private OAuthConsumer mConsumer;
private OAuthProvider mProvider;
private ProgressDialog mSpinner;
private WebView mWebView;
/**
* Handler to run shit on the UI thread
*
* #author Grantland Chew
*/
private class H extends Handler {
#Override
public void handleMessage (Message msg) {
Bundle data = msg.getData();
switch (msg.what) {
case RETRIEVE_REQUEST_TOKEN: {
mWebView.loadUrl(data.getString(KEY_URL));
} break;
case RETRIEVE_ACCESS_TOKEN: {
} break;
default: {
}
}
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.twitter_layout);
Intent intent = getIntent();
mConsumer = (OAuthConsumer)intent.getSerializableExtra(Twitter.EXTRA_CONSUMER);
String authorizeParams = intent.getStringExtra(Twitter.EXTRA_AUTHORIZE_PARAMS);
mMainThreadHandler = new H();
mProvider = new CommonsHttpOAuthProvider(
Twitter.REQUEST_TOKEN,
Twitter.ACCESS_TOKEN,
Twitter.AUTHORIZE + authorizeParams);
mProvider.setOAuth10a(true);
mSpinner = new ProgressDialog(this);
mSpinner.setMessage(getResources().getString(R.string.loading_loading));
mSpinner.setOnCancelListener(new OnCancelListener() {
#Override public void onCancel(DialogInterface dialog) {
cancel();
}
});
mWebView = (WebView)findViewById(R.id.twitter_webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setSaveFormData(false);
mWebView.getSettings().setSavePassword(false);
mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
mWebView.setWebViewClient(new TwitterWebViewClient());
// Retrieve request_token on background thread
Thread thread = new Thread() {
#Override
public void run() {
try {
Message msg = new Message();
msg.what = RETRIEVE_REQUEST_TOKEN;
Bundle bundle = new Bundle();
bundle.putString(KEY_URL, mProvider.retrieveRequestToken(mConsumer, Twitter.CALLBACK_URI));
msg.setData(bundle);
if (DEBUG) Log.d(TAG, "url: " + bundle.getString(KEY_URL));
mMainThreadHandler.sendMessage(msg);
} catch (OAuthException e) {
error(e);
}
}
};
thread.start();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (KeyEvent.KEYCODE_BACK == keyCode) {
cancel();
return true; // consume event
}
return false; // don't consume event
}
private void error(Throwable error) {
Intent intent = this.getIntent();
intent.putExtra(Twitter.EXTRA_ERROR, error.getMessage());
this.setResult(RESULT_OK, intent);
finish();
}
private void cancel() {
Intent intent = this.getIntent();
this.setResult(RESULT_CANCELED, intent);
finish();
}
private void complete(String accessKey, String accessSecret) {
Intent intent = this.getIntent();
intent.putExtra(Twitter.EXTRA_ACCESS_KEY, accessKey);
intent.putExtra(Twitter.EXTRA_ACCESS_SECRET, accessSecret);
this.setResult(RESULT_OK, intent);
finish();
}
private void retrieveAccessToken(final Uri uri) {
Thread thread = new Thread() {
#Override
public void run() {
try {
if (DEBUG) Log.d(TAG, uri.toString());
String oauth_token = uri.getQueryParameter(OAuth.OAUTH_TOKEN);
String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
if (DEBUG) Log.d(TAG, oauth_token);
if (DEBUG) Log.d(TAG, verifier);
mConsumer.setTokenWithSecret(oauth_token, mConsumer.getConsumerSecret());
mProvider.retrieveAccessToken(mConsumer, verifier);
complete(mConsumer.getToken(), mConsumer.getTokenSecret());
} catch (OAuthException e) {
error(e);
}
}
};
thread.start();
}
private class TwitterWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (DEBUG) Log.d(TAG, url);
Uri uri = Uri.parse(url);
if (uri != null && Twitter.CALLBACK_SCHEME.equals(uri.getScheme())) {
String denied = uri.getQueryParameter(Twitter.DENIED);
if (denied != null) {
cancel();
} else {
retrieveAccessToken(uri);
}
return true;
}
return false;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (DEBUG) Log.d(TAG, "Webview loading URL: " + url);
if (view.getVisibility() != View.INVISIBLE && !mSpinner.isShowing()) {
mSpinner.show();
}
}
#Override
public void onPageFinished(WebView view, String url) {
mSpinner.dismiss();
view.setVisibility(View.VISIBLE);
}
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
error(new TwitterError(description, errorCode, failingUrl));
}
};
}
I recommend you use this library. This library as explained in the book "Learning Android, 2nd Edition": It has been stripped down to the bare essentials, making it easy for you to peek at it's source code and see it's inner workings, if you care to do so. It also supports Twitter’s older API that allows for simple authentication (username and password) versus the new OAuth authentication. is much simpler to integrate and use than the one you are using. Again it depends what you want to actually do. if your purpose is to learn and you are new to Java and Android this is recommended due to focus on learning the concept rather than library and API.
I can recommend you this library - https://github.com/antonkrasov/AndroidSocialNetworks
But your issue in permission of your app.
Open your app settings and go to permissions tab:
Then select Read and Write and save:
Now all should work.
I'm having some kind of logical problem with my code for saving on internal storage.
I created two methods in the class pet for load and save where I'm trying to save and load an instance of pet. I don't get any error messages in logcat, but nothing is saved when I quit and then open the application again.
package Model;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import edu.chl.dat255.sofiase.readyforapet.CreatePet;
import android.content.Context;
public class Pet implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
PetMood petMood = new PetMood();
private int hungerCounter;
private int walkCounter;
private int playCounter;
/**
* Method that increases mood bar while eating
*
* #return String with the pet's reaction
*/
public String eat() {
//walkCounter = petMood.getWalkMood();
hungerCounter = petMood.getFoodMood();
//playCounter = petMood.getPlayMood();
if (hungerCounter < 5) {
hungerCounter = hungerCounter + 1;
petMood.setFoodMood(hungerCounter);
return "Yummie!";
}
else{
return "I am full";
}
}
/**
* Method that increases mood bar while walking
* and decides that the dog can't walk when it is too hungry or too tired
*
* #return String with the pet's reaction
*/
public String walk() {
walkCounter = petMood.getWalkMood();
hungerCounter = petMood.getFoodMood();
playCounter = petMood.getPlayMood();
if (hungerCounter < 3 && walkCounter < 5)
return "I'm too hungry!";
else if (playCounter + walkCounter > 6)
return "I'm tired! I want to rest!";
else if (walkCounter < 5) {
walkCounter = walkCounter + 1;
petMood.setWalkMood(walkCounter);
return "Yeey! Great exercise!";
}
else{
return "I'm tired! I want to rest!";
}
}
/**
* Method that increases mood bar while playing
* and decides that the dog can't play when it is too hungry or too tired
*
* #return String with the pet's reaction
*/
public String play() {
walkCounter = petMood.getWalkMood();
hungerCounter = petMood.getFoodMood();
playCounter = petMood.getPlayMood();
if (playCounter + walkCounter > 6) {
return "I'm tired! I want to rest!";
}
else if (hungerCounter <3 && playCounter < 5)
return "I'm too hungry!";
else if (playCounter < 5 ) {
playCounter = playCounter + 1;
petMood.setPlayMood(playCounter);
return "Yeey! Lots of fun!";
}
else{
return "I'm tired! I want to rest!";
}
}
public void save(String FILENAME, Context context) throws FileNotFoundException, IOException{
FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
ObjectOutputStream savedPet = new ObjectOutputStream(fos);
savedPet.writeObject(context.getApplicationContext());
savedPet.close();
}
public static Pet load(String FILENAME, Context context) throws FileNotFoundException, IOException, ClassNotFoundException{
FileInputStream fis = context.openFileInput(FILENAME);
ObjectInputStream ois = new ObjectInputStream(fis);
Pet pet = (Pet) ois.readObject();
ois.close();
CreatePet.setPet(pet);
return pet;
}
}
package edu.chl.dat255.sofiase.readyforapet;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import Model.Dog;
import Model.Pet;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class CreatePet extends Activity implements OnClickListener, Serializable { //lagt till interface serializivble. kanske inte n�dv�ndigt
/**
*
*/
private static final long serialVersionUID = 1L;
String petName;
private static Dog dog;
String FILENAME = "pet_file.dat";//lagts till f�r nullpointerexeption
/**
* onCreate Method
*
*
* #param savedInstanceState - Bundle
*/
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView(R.layout.createpet);
Button create = (Button) findViewById(R.id.puppy_settings);
create.setOnClickListener(this);
}
public void onClick (View v){
startActivity(new Intent(CreatePet.this, PetActivity.class));
EditText setName = (EditText) findViewById(R.id.edit_pet_name);
petName = setName.getText().toString();
dog = new Dog(petName);
try {
dog.save("pet_file.dat", this);
} catch (FileNotFoundException e) {
System.out.print("File not found kastad i CreatePet");
e.printStackTrace();
} catch (IOException e) {
System.out.print("IOException kastad i CreatePet");
e.printStackTrace();
}
}
/**
* getPet Method
*
* makes the created pet available to other classes
*
* #return dog - an instance of the class Dog
*/
public static Pet getPet(){
return dog;
}
/**
* getPet Method
*
* makes the created pet available to other classes
*
* #return dog - an instance of the class Dog
*/
public static void setPet(Pet pet){
dog = (Dog) pet;
}
}
package edu.chl.dat255.sofiase.readyforapet;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import Model.Pet;
import Model.Dog;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class SelectGame extends Activity implements Serializable {// la till f�r att objektet m�ste vara serializible
private static final long serialVersionUID = 1L;
TextView failMessage;
String FILENAME = "pet_file.dat";// lgts till f�r nullpointerexep
/**
* onCreate method
*
* #param savedInstanceState - Bundle
*/
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView(R.layout.selectgame);
//The continue button reacts to a click and starts PetActivity
Button continuePreviousGame = (Button) findViewById(R.id.continuegame);
continuePreviousGame.setOnClickListener(new OnClickListener() {
/**
* Method onClick for the continue previous game button
*
* #param v - View
*/
public void onClick (View v){
try {
Pet.load("pet_file.dat",SelectGame.this);
} catch (FileNotFoundException e) {
System.out.print("File not found ");
e.printStackTrace();
} catch (IOException e) {
System.out.print("IO Exception ");
e.printStackTrace();
} catch (ClassNotFoundException e) {
System.out.print("Class not found exception ");
e.printStackTrace();
}
if (CreatePet.getPet() != null){
startActivity(new Intent(SelectGame.this, PetActivity.class));
}
else{
failMessage = (TextView) findViewById(R.id.failmessage);
failMessage.setText("Create a pet first!");
}
}
}
);
//To send the button CreateNewPet to the activity CreatePet
Button createNewPet = (Button) findViewById(R.id.createnewpet);
createNewPet.setOnClickListener(new OnClickListener() {
/**
* Method onClick for the create new pet button
*
* #param v - View
*/
public void onClick (View v){
startActivity(new Intent(SelectGame.this, CreatePet.class));
}
}
);
}
}
You are saving the wrong object. Your code saves a Context and tries to reload it as a Pet.
Instead of
savedPet.writeObject(context.getApplicationContext());
you should be doing
savedPet.writeObject(this);
Till now I have gone through various forums and found that we have to get the token to send email. I have tried in various ways but not able to send mail to any. Can anyone please help me by sending various links related to this.
This is my Mail.java class
package com.mycomp.android.test;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class Mail extends javax.mail.Authenticator {
private Multipart attachements;
private String fromAddress = "";
private String accountEmail = "";
private String accountPassword = "";
private String smtpHost = "smtp.gmail.com";
private String smtpPort = "465"; // 465,587
private String toAddresses = "";
private String mailSubject = "";
private String mailBody = "";
public Mail() {
attachements = new MimeMultipart();
}
public Mail(String user, String pass) {
this();
accountEmail = user;
accountPassword = pass;
}
public boolean send() throws Exception {
Properties props = new Properties();
//props.put("mail.smtp.user", d_email);
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", smtpPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.debug", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", smtpPort);
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
try {
Session session = Session.getInstance(props, this);
session.setDebug(true);
MimeMessage msg = new MimeMessage(session);
// create the message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
//fill message
messageBodyPart.setText(mailBody);
// add to multipart
attachements.addBodyPart(messageBodyPart);
//msg.setText(mailBody);
msg.setSubject(mailSubject);
msg.setFrom(new InternetAddress(fromAddress));
msg.addRecipients(Message.RecipientType.TO,
InternetAddress.parse(toAddresses));
msg.setContent(attachements);
Transport transport = session.getTransport("smtps");
transport.connect(smtpHost, 465, accountEmail, accountPassword);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
return true;
} catch (Exception e) {
return false;
}
}
public void addAttachment(String filename) throws Exception {
BodyPart messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
// messageBodyPart.setFileName("filename");
attachements.addBodyPart(messageBodyPart);
}
#Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(accountEmail, accountPassword);
}
/**
* Gets the fromAddress.
*
* #return <tt> the fromAddress.</tt>
*/
public String getFromAddress() {
return fromAddress;
}
/**
* Sets the fromAddress.
*
* #param fromAddress <tt> the fromAddress to set.</tt>
*/
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
/**
* Gets the toAddresses.
*
* #return <tt> the toAddresses.</tt>
*/
public String getToAddresses() {
return toAddresses;
}
/**
* Sets the toAddresses.
*
* #param toAddresses <tt> the toAddresses to set.</tt>
*/
public void setToAddresses(String toAddresses) {
this.toAddresses = toAddresses;
}
/**
* Gets the mailSubject.
*
* #return <tt> the mailSubject.</tt>
*/
public String getMailSubject() {
return mailSubject;
}
/**
* Sets the mailSubject.
*
* #param mailSubject <tt> the mailSubject to set.</tt>
*/
public void setMailSubject(String mailSubject) {
this.mailSubject = mailSubject;
}
/**
* Gets the mailBody.
*
* #return <tt> the mailBody.</tt>
*/
public String getMailBody() {
return mailBody;
}
/**
* Sets the mailBody.
*
* #param mailBody <tt> the mailBody to set.</tt>
*/
public void setMailBody(String mailBody) {
this.mailBody = mailBody;
}
}
This is my MailSenderActivity.java class
package com.mycomp.android.test;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Pattern;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MailSenderActivity extends Activity {
AccountManager am = AccountManager.get(this); // "this" references the current Context
Pattern emailPattern = Patterns.EMAIL_ADDRESS;
Account[] accounts = am.getAccountsByType("com.google");
private static final String GMAIL_EMAIL_ID = "From Email Address";
private static final String GMAIL_ACCOUNT_PASSWORD = "password";
private static final String TO_ADDRESSES = "To Email Address";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
writeFile();
final Button send = (Button) this.findViewById(R.id.send);
send.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new MailSenderActivity.MailSender().execute();
}
});
}
private File imageFile;
private boolean writeFile() {
imageFile = new File(
getApplicationContext().getFilesDir() + "/images/",
"sample.png");
String savePath = imageFile.getAbsolutePath();
System.out.println("savePath :" + savePath + ":");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(savePath, false);
} catch (FileNotFoundException ex) {
String parentName = new File(savePath).getParent();
if (parentName != null) {
File parentDir = new File(parentName);
if ((!(parentDir.exists())) && (parentDir.mkdirs()))
try {
fileOutputStream = new FileOutputStream(savePath, false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
// here i am using a png from drawable resources as attachment. You can use your own image byteArray while sending mail.
Bitmap bitmap = BitmapFactory.decodeResource(
MailSenderActivity.this.getResources(), R.drawable.english);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] imgBuffer = stream.toByteArray();
boolean result = true;
try {
fileOutputStream.write(imgBuffer);
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
result = false;
} catch (IOException e2) {
e2.printStackTrace();
result = false;
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
result = false;
}
}
}
return result;
}
class MailSender extends AsyncTask<Void, Integer, Integer> {
ProgressDialog pd = null;
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd = new ProgressDialog(MailSenderActivity.this);
pd.setTitle("Uploading...");
pd.setMessage("Uploading image. Please wait...");
pd.setCancelable(false);
pd.show();
}
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#doInBackground(Params[])
*/
#Override
protected Integer doInBackground(Void... params) {
Mail m = new Mail(GMAIL_EMAIL_ID, GMAIL_ACCOUNT_PASSWORD);
String toAddresses = TO_ADDRESSES;
m.setToAddresses(toAddresses);
m.setFromAddress(GMAIL_EMAIL_ID);
m.setMailSubject("This is an email sent using my Mail JavaMail wrapper from an Android device.");
m.setMailBody("Email body.");
// try {
// ZipUtility.zipDirectory(new File("/mnt/sdcard/images"),
// new File("/mnt/sdcard/logs.zip"));
// } catch (IOException e1) {
// Log.e("MailApp", "Could not zip folder", e1);
// }
try {
String path = imageFile.getAbsolutePath();
System.out.println("sending path:" + path + ":");
m.addAttachment(path);
// m.addAttachment("/mnt/sdcard/logs.zip");
if (m.send()) {
System.out.println("Message sent");
return 1;
} else {
return 2;
}
} catch (Exception e) {
Log.e("MailApp", "Could not send email", e);
}
return 3;
}
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pd.dismiss();
if (result == 1)
Toast.makeText(MailSenderActivity.this,
"Email was sent successfully.", Toast.LENGTH_LONG)
.show();
else if (result == 2)
Toast.makeText(MailSenderActivity.this, "Email was not sent.",
Toast.LENGTH_LONG).show();
else if (result == 3)
Toast.makeText(MailSenderActivity.this,
"There was a problem sending the email.",
Toast.LENGTH_LONG).show();
}
}
}
If I set GMAIL_EMAIL_ID,GMAIL_ACCOUNT_PASSWORD and TO_ADDRESSES manually I am able to send message. But i have get the default GMAIL_EMAIL_ID and GMAIL_ACCOUNT_PASSWORD whisch are already in app of mobile.
You can use this to send email with attachments:
public static void sendEmail(Context context, String emailTo, String emailCC, String subject, String emailText, String type, List<String> filePaths) {
//need to "send multiple" to get more than one attachment
final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
emailIntent.setType("image/png");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{emailTo});
emailIntent.putExtra(android.content.Intent.EXTRA_CC, new String[]{emailCC});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, emailText);
//has to be an ArrayList
ArrayList<Uri> uris = new ArrayList<Uri>();
//convert from paths to Android friendly Parcelable Uri's
if(filePaths != null) {
for (String file : filePaths) {
File fileIn = new File(file);
Uri u = Uri.fromFile(fileIn);
uris.add(u);
}
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
}
try {
context.startActivity(Intent.createChooser(emailIntent, context.getString(R.string.send_email_using_message)));
}catch (ActivityNotFoundException e) {
new DigitalReplicaDialog(context, context.getResources().getString(R.string.email_not_configured_warning)).show();
}
}