volley network image view and request headers - android

I have network image view which should get populated when I get the response back from the server in JSON format.
I get back a URL in json and I go to URL and show the image in my list view in android. However, this works fine if I use any image which is publicly hosted on internet.
In my case server is on IBM Domino and everything is in the domino database. The URL won't open unless i have user credentials to do so.
For general request responses using volley, I set a session ID in request headers, telling the domino server that i have authenticated myself already. however, in case of network Image view, I am unable to proceed as i do not know how to authenticate myself with the server.
The images do not show in the list view and I see following in my logcat
SkImageDecoder::Factory returned null
I tried to open the same URL in browser, it asks for my user ID password and if I login, I am able to download the jpg file on my system.
Is there a way to set my http request headers for network image view ? How shall I proceed in this case ? Please help
Thanks

NetworkImageView uses ImageLoader which internally makes ImageRequests using makeImageRequest
ImageRequest extends from Request. Request class has a getHeaders() method which allows to set request headers.
So if you can override makeImageRequest method of ImageLoader and then override getHeaders() for ImageRequest inside it, you should be able to set your request headers for NetworkImageView
#Override
protected Request<Bitmap> makeImageRequest(String requestUrl, int maxWidth, int maxHeight, final String cacheKey) {
//return super.makeImageRequest(requestUrl, maxWidth, maxHeight, cacheKey);
return new ImageRequest(requestUrl, new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap response) {
onGetImageSuccess(cacheKey, response);
}
}, maxWidth, maxHeight,
Bitmap.Config.RGB_565, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
onGetImageError(cacheKey, error);
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
params.put("Authorization", YOUR_TOKEN);
return params;
}
};
}

I tried using the above ImageLoader, but couldn't seem to override the makeImageRequest method.
When looking at the Volley implementation I couldn't see the same method signature, so I used the same approach by #random - here's my CustomImageLoader.
public class CustomImageLoader extends ImageLoader {
private Context mContext;
/**
* Constructs a new ImageLoader.
*
* #param queue The RequestQueue to use for making image requests.
* #param imageCache The cache to use as an L1 cache.
*/
public CustomImageLoader(Context aContext, RequestQueue queue, ImageCache imageCache) {
super(queue, imageCache);
mContext = aContext;
}
#Override
protected Request<Bitmap> makeImageRequest(String requestUrl, int maxWidth, int maxHeight,
ImageView.ScaleType scaleType, final String cacheKey,
final ImageRequest.Transformation transformation) {
return new ImageRequest(requestUrl, new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap response) {
onGetImageSuccess(cacheKey, response);
}
}, maxWidth, maxHeight, scaleType, Bitmap.Config.RGB_565, transformation, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
onGetImageError(cacheKey, error);
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return getHeaders(mContext); //*YOUR* method for getting headers
}
};
}
}

Related

Is there an way to access AWS RDS database by StringRequest URL in android app?

I'm very new to server system and have been struggling over making login system work on android app that I'm developing.
I connected RDS database with AWS EC2 server but have no idea how to access to RDS database with app.
Here is class I'm using for server:
public class ValidateRequest extends StringRequest {
final static private String URL = "https://localhost/UserValidate.php";
private Map<String, String> parameters;
// send parameter values to database by posting method
public ValidateRequest(String userID, Response.Listener<String> listener) {
super(Method.POST, URL, listener, null);
parameters = new HashMap<>();
parameters.put("userID",userID);
}
#Override
protected Map<String, String> getParams(){
return parameters;
}
}
When program is executed, it doesn't display any error messages. I'm thinking my URL variable is set wrong but have no idea how to fix it. Can anyone suggest what to do here?
my php files are located under /var/www/html remote site. Any help will be appreciated.
I realize this is a month late but I'm guessing this will be useful for anyone else that has the same problem. This answer assumes you have made the necessary security group settings for the rds instance (like making it accessible publicly, although I would only recommend doing that for development purposes).
This answer uses volley as well albeit using a singleton class for the request queue.
Solution -
1. PHP constants file. (Declare your database constants)
define ('DB_HOST', 'aws rds access point goes here');
define ('DB_USER', 'rds user name goes here ' );
define ('DB_PASSWORD', 'rds password goes here ');
2. PHP Connection file. (Initiate connection)
require_once "constants.php";
$con = new mysqli(DB_HOST,DB_USER,DB_PASSWORD);
if($con)
{
$sql = "SQL Query";
$result = mysqli_query($con,$sql);
//Whatever you echo here will be treated as the response at the android end
//Can be JSON,string etc.
}
3. Java file. (Initiate String request in android)
This is an example of how it would look like if you were trying to login users into your application.
private void login(final String emailText, final String passText) {
final StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),error.toString(),Toast.LENGTH_SHORT).show();
System.out.println("Error is " + error.toString());
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map <String,String> params = new HashMap<String,String>();
params.put(Constants.KEY_EMAIL,emailText);
params.put(Constants.KEY_PASSWORD,passText);
return params;
}
};
MySingleton.getInstance(this).addToRequestQueue(request);
}
4. Java singleton class. (Recommended to use if you're making a lot of requests)
public class MySingleton {
private static MySingleton instance;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private static Context ctx;
private MySingleton(Context context) {
ctx = context;
requestQueue = getRequestQueue();
imageLoader = new ImageLoader(requestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
#Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized MySingleton getInstance(Context context) {
if (instance == null) {
instance = new MySingleton(context);
}
return instance;
}
public RequestQueue getRequestQueue() {
if (requestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
}
return requestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}

Upload bitmap file to server using volley and codeigniter

I am using volley to upload my bitmap file to the server. In server side, i'm using codeigniter framework to do that job but i've got response from the server when I trying to upload the file that says,
"you did not select a file to upload"
here is the code
Volley
public void uploadImage(final Context context, final Bitmap bitmap) {
String url = "https://zenosama1111.000webhostapp.com/Upload/do_upload";
RequestQueue requestQueue = Volley.newRequestQueue(context);
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("thumbnail", bitmapToString(bitmap));
return params;
}
};
requestQueue.add(request);
}
server side
public function do_upload()
{
$config['upload_path'] = './thumbnails/';
$config['allowed_types'] = 'gif|jpg|png|jpeg';
$config['max_size'] = 100;
$config['max_width'] = 160;
$config['max_height'] = 100;
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload('thumbnail'))
{
echo false;
}
else
{
echo true;
}
$error = array('error' => $this->upload->display_errors());
echo json_encode($error);
}
other tutorials are using pure php code to upload a file but not in codeigniter..
somebody know how can i fix this problem?
This $this->upload->do_upload($this->input->post('thumbnail')) or $this->upload->do_upload('thumbnail') won't work.
do_upload will only work with an item from the $_FILES array (different than post array) and the parameter of do_upload($param) must be the fieldname of the file input.
e.g. <input name="userfile" type="file"> => do_upload('userfile')
It isn't intended to be used the way you are using it as your item is in the post array. Hence maybe a file_put_contents($filename, $this->input->post('thumbnail')); would work for your needs.
If you could get the item to be in the $_FILES array then you might have a chance of using the CI upload library.

How to implement a login in Android using Volley?

I have a LoginActitvity with two textfields for the username and password and a login-button. When the user presses the button, the app starts an async task. The async task implements my VolleyHandler. It checks if the login parameters are correct and fetches some user data (using volley and json). While doing this, a ProgressDialog appears. When the async task is finished, it starts an intent to the MainActivity in the onPostExecute method.
Now to my question: Is it a good idea to make volley-requests in the async task, or do you have a better solution?
Thanks.
You cannot use asynctask. Volley care about it. You can use callback for work with data and ui.
Looks like this:
public class LoginActivity extends SinglePaneActivity implements DownloadCallback {
//...
public void sendRequest(){
Downloader download = new Download(this);
downloader.download(userName, password);
progresbar.show();
}
public void requestFinish(){
progersbar.dismis();
//... continue
}
}
callback:
public interface DownloadCallback {
void requestFinish();
}
in class downloader
private RequestQueue requestQueue;
DownloadCallback mcallback;
public void Downloader(DownloadCallback callback){
mCallback = callback;
requestQueue = Volley.newRequestQueue(mContext);
initVolleyListeners();
}
private void initVolleyListeners() {
mSuccessListener = new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
mCallback.requestFinish();
}
};
mErrorListener = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mCallback.requestFinish();
}
};
public void download(String user, String pass){
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, createJson(user, pass), mSuccessListener , mErrorListener ) {
//header for send JSON to server
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
return headers;
}
};
requestQueue.add(jsonObjectRequest );
}
And one point. Don't send user name in json. You send it as param in header. Use this application/x-www-form-urlencoded and set up pass an username as params in header.
Update:
Now It will work. Sorry I wrote it in a hurry.
Article about how callback work

How to put volley coding in main acitivity.java

This Android app is using Android Studio. The function is to scan and display data from the beacon/eddystone. The app already functions and after the scanning stops, the data saves to the local file. I need to transfer the data to the server. How can i insert the volley coding to the mainacitivity.java. I tried to put under the stopscanning button, but it shows error. Im really beginners to learn about android studio.
Here is the coding:
private void stopScanning(Button scanButton) {
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
// TODO - OK, what now then?
}
String scanData = logString.toString();
if (scanData.length() > 0)
{
public class MainActivity extends AppCompatActivity {
//The values of these variables will be fetched by the file(Where you will store data)
private String PREFERENCE_SCANINTERVAL = "scanInterval";
private String PREFERENCE_TIMESTAMP = "timestamp";
private String PREFERENCE_POWER = "power";
private String PREFERENCE_PROXIMITY = "proximity";
private String PREFERENCE_RSSI = "rssi";
private String PREFERENCE_MAJORMINOR = "majorMinor";
private String PREFERENCE_UUID = "uuid";
private String PREFERENCE_INDEX = "index";
private String PREFERENCE_LOCATION = "location";
private String PREFERENCE_REALTIME = "realTimeLog";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url = "http://beaconscanner.byethost33.com/beaconscanner.php";//This is the url of your server where you will be sending the data to.
//StringRequest is a class in the Volley Library.
//The constructor of this class has four parameters.
// 1 parameter is Request.Method.POST =this specifies the method type, That is post.
//2 parameter is the url you will be sending the request to.That is the server
//3 parameter is the response listener , It will listen for any response from your server . you will be able to fetch the response from the server using this.
//4 parameter is the error listener, it will listen for any error's during the connection or etc.
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//Here you will be able to fetch the response coming from the server.
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
})
//This is the method we override.
{
//This is method is used to send the data to the server for post methods. This method returns all the data you want to send to server. This is how you send data using Volley.
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("scanInterval",PREFERENCE_SCANINTERVAL);
params.put("timestamp",PREFERENCE_SCANINTERVAL);
params.put("power",PREFERENCE_POWER);
params.put("proximity",PREFERENCE_PROXIMITY);
params.put("rssi",PREFERENCE_RSSI);
params.put("majorMinor",PREFERENCE_MAJORMINOR);
params.put("uuid",PREFERENCE_UUID);
params.put("index",PREFERENCE_INDEX);
params.put("location",PREFERENCE_LOCATION);
params.put("realTimelog",PREFERENCE_REALTIME);
return params;
}
};//The constructor ends here.
Volley.newRequestQueue(this).add(request);// This is the main potion of this code. if you dont add this you will not be able to send the request to your server. this helps you to send it.
}
}
// Write file
fileHelper.createFile(scanData);
// Display file created message.
Toast.makeText(getBaseContext(),
"File saved to:" + getFilesDir().getAbsolutePath(),
Toast.LENGTH_SHORT).show();
scanButton.setText(MODE_STOPPED);
} else {
// We didn't get any data, so there's no point writing an empty file.
Toast.makeText(getBaseContext(),
"No data captured during scan, output file will not be created.",
Toast.LENGTH_SHORT).show();
scanButton.setText(MODE_STOPPED);
}
}
Please add your stacktrace. Also I guess that you want to send the data using the body not the params :). In that case, call the request using the following signature:
new JsonObjectRequest(Request.Method.POST, url, new JSONObject(bodyData), new Response.Listener<JSONObject>() { }
public void sendMyData(HashMap map) {
String url = "http://"....";
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressBar.setVisibility(View.INVISIBLE);
try {// to receive server response, in this example it's jsonArray
JSONArray jsonArray = new JSONArray(response);
//code
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
}) {
#Override
public String getBodyContentType() { // if your server uses java restfull webservice , you have to override this content type
return "application/json";
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {// parameters which should server receive
Map<String, String> parameters =map;
return parameters;
}
};
requestQueue.add(request);
}

Response coming from Volley the first time only

I'm using Volley to fetch data from server. I have 2 activities, Activity A and B. Both uses Volley and the same Request Queue via a Singleton to fetch data. Everything works fine in Activity A, and when I start Activity B I get Volley's response.
The problem is, if I finish from activity B and move to A, and then start B again, Volley seems to fail to get a response. What am I doing wrong?
My Singleton
public class CustomVolleyRequestQueue {
private static CustomVolleyRequestQueue mInstance;
private static Context mCtx;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private CustomVolleyRequestQueue(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
mImageLoader = new ImageLoader(mRequestQueue, new LruBitmapCache(
LruBitmapCache.getCacheSize(mCtx)));
}
public static synchronized CustomVolleyRequestQueue getInstance(Context context) {
if (mInstance == null) {
mInstance = new CustomVolleyRequestQueue(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
Cache cache = new DiskBasedCache(mCtx.getCacheDir(), 10 * 1024 * 1024);
Network network = new BasicNetwork(new HurlStack());
mRequestQueue = new RequestQueue(cache, network);
// Don't forget to start the volley request queue
mRequestQueue.start();
}
return mRequestQueue;
}
public ImageLoader getmImageLoader(){
return mImageLoader;
}
}
My Custom request
public class CustomJSONObjectRequest extends JsonObjectRequest{
private Priority mPriority;
public CustomJSONObjectRequest(int method, String url, JSONObject jsonRequest,
Response.Listener<JSONObject> listener,
Response.ErrorListener errorListener) {
super(method, url, jsonRequest, listener, errorListener);
//this.setShouldCache(true);
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
return headers;
}
#Override
public RetryPolicy getRetryPolicy() {
// here you can write a custom retry policy
return super.getRetryPolicy();
}
public void setPriority(Priority priority) {
mPriority = priority;
}
#Override
public Priority getPriority() {
return mPriority == null ? Priority.NORMAL : mPriority;
}
}
I perform and add the request on the onStart of my Activity B as follows,
protected void onStart() {
super.onStart();
mQueue = CustomVolleyRequestQueue.getInstance(this.getApplicationContext())
.getRequestQueue();
final CustomJSONObjectRequest jsonRequest = new CustomJSONObjectRequest(Request.Method
.GET, url,
new JSONObject(), this, this);
jsonRequest.setTag(REQUEST_TAG);
jsonRequest.setPriority(Request.Priority.HIGH);
mQueue.add(jsonRequest);
setupRecyclerView(rv, rv2, rv3);
}
My activity B Implements the Response Listener, where I simple parse the JSON and display the data on the UI.
I've been going on about this issue for a quite while, I've learned the tips and tricks of other features of Volley, caching, Ignoring requests, going deep to play around with the library and using it with other libraries. Yet, I still fail to see what I could be doing wrong here.
Alright found my solution, and it's quite embarrassing. I was using a static URL to add the GET parameter. Since it was my first time using Volley, I didn't know how to add GET parameters to requests, was supposed to come back to it later on. I forgot.
So basically I am concatenating the GET parameter value the next time I move to the next activity, hence getting a null response from the server since those values don't exist there.
It was too simple to notice, I should have been more careful with my debugging.

Categories

Resources