how to get binary format values from video file? [duplicate] - java

I want to upload a video in web server. I got the service which to i want to pass a file in binary format how can i do this ?
I have tried to convert the video file into binary format with the help of base64..?
public class binaryformat extends Activity {
private String strAttachmentCoded;
Button b1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1=(Button)findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
File file = new File("/mnt/sdcard/C:/Program Files (x86)/Wowza Media Systems/Wowza Media Server 3.1.2/content/sample.mp4");
FileInputStream objFileIS = null;
try
{
objFileIS = new FileInputStream(file);
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
ByteArrayOutputStream objByteArrayOS = new ByteArrayOutputStream();
byte[] byteBufferString = new byte[1024];
try
{
for (int readNum; (readNum = objFileIS.read(byteBufferString)) != -1;)
{
objByteArrayOS.write(byteBufferString, 0, readNum);
System.out.println("read " + readNum + " bytes,");
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] byteBinaryData = Base64.encode((objByteArrayOS.toByteArray()), Base64.DEFAULT);
strAttachmentCoded = new String(byteBinaryData);
}
});
}
}

I have experienced in my 3 application that it is good if use XML to send the IMAGE or VIDEO over server.
Sending IMAGE or VIDEO in the form of base64 String in the XML is best if you want to upload a IMAGE or VIDEO in ANDROID.
public static String uploadMultiplePhoto(String url, String xmlString) {
String responseString = "";
try {
//instantiates httpclient to make request
DefaultHttpClient httpclient = new DefaultHttpClient();
//url with the post data
HttpPost request = new HttpPost(url);
//convert parameters into JSON object
//JSONObject holder = new JSONObject(jsonObjString);
//passes the results to a string builder/entity
StringEntity se = new StringEntity(xmlString);
//sets the post request as the resulting string
request.setEntity(se);
//sets a request header so the page receving the request
//will know what to do with it
request.setHeader("Accept", "application/xml");
/*request.setHeader("Content-type", "application/xml");*/
//Handles what is returned from the page
ResponseHandler<String> responseHandler = new BasicResponseHandler();
responseString = httpclient.execute(request, responseHandler);
} catch (Exception exception) {
exception.printStackTrace();
}
return responseString;
}

Related

Empty string when reading data sent from server

I'm having trouble with this code. The variable result should be filled from the response of the server, but for any reason, it keeps returning an empty string.
This is the entire code:
public class FragmentRally extends Fragment {
public FragmentRally() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_fragment_rally, container, false);
new AsyncFetch().execute();
return rootView;
}
// CONNECTION_TIMEOUT and READ_TIMEOUT are in milliseconds
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private RecyclerView vistaRallye;
private AdapterRallye adaptadorRallye;
private class AsyncFetch extends AsyncTask<String, String, String> {
ProgressDialog pdLoading = new ProgressDialog(getActivity());
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tCarregant...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected String doInBackground(String... params) {
try {
// Enter URL address where your json file resides
// Even you can make call to php file which returns json data
url = new URL("http://www.rallyecat.esy.es/Obtenir_events.php");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("GET");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("No hi ha connexió a internet.");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
pdLoading.dismiss();
List<DataRallye> data = new ArrayList<>();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
// Extract data from json and store into ArrayList as class objects
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
DataRallye dadesrallye = new DataRallye();
dadesrallye.RallyeNom = json_data.getString("nom");
dadesrallye.RallyeTipus = json_data.getString("tipus");
dadesrallye.RallyeDataI = json_data.getString("datai");
dadesrallye.RallyeDataF = json_data.getString("dataf");
dadesrallye.RallyeCiutat = json_data.getString("ciutat");
dadesrallye.RallyeOrganitzacio = json_data.getString("organitzacio");
dadesrallye.RallyeFoto = json_data.getString("foto");
data.add(dadesrallye);
}
// Setup and Handover data to recyclerview
vistaRallye = (RecyclerView) getView().findViewById(R.id.llistarallyes);
adaptadorRallye = new AdapterRallye(getActivity(), data);
vistaRallye.setAdapter(adaptadorRallye);
vistaRallye.setLayoutManager(new LinearLayoutManager(getActivity()));
} catch (JSONException e) {
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
The problem appears here:
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
This variable, RESULT is passed here, where I do the JSON Parse. But as it is empty, it goes directly to the catch exception:
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
pdLoading.dismiss();
List<DataRallye> data = new ArrayList<>();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
// Extract data from json and store into ArrayList as class objects
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
DataRallye dadesrallye = new DataRallye();
dadesrallye.RallyeNom = json_data.getString("nom");
dadesrallye.RallyeTipus = json_data.getString("tipus");
dadesrallye.RallyeDataI = json_data.getString("datai");
dadesrallye.RallyeDataF = json_data.getString("dataf");
dadesrallye.RallyeCiutat = json_data.getString("ciutat");
dadesrallye.RallyeOrganitzacio = json_data.getString("organitzacio");
dadesrallye.RallyeFoto = json_data.getString("foto");
data.add(dadesrallye);
}
// Setup and Handover data to recyclerview
vistaRallye = (RecyclerView) getView().findViewById(R.id.llistarallyes);
adaptadorRallye = new AdapterRallye(getActivity(), data);
vistaRallye.setAdapter(adaptadorRallye);
vistaRallye.setLayoutManager(new LinearLayoutManager(getActivity()));
} catch (JSONException e) {
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
}
Here is the JSON generated from a PHP file on our website:
[{"id_rally":"1","nom":"45e rallye costa brava","tipus":"velocitat i regularitat","datai":"2017-06-20","dataf":"2017-06-22","ciutat":"Girona","organitzacio":"rallyclassics ","foto":"brava.png"},{"id_rally":"2","nom":"26e rallye igualada","tipus":"velocitat","datai":"2017-08-13","dataf":"2017-08-16","ciutat":"Igualada","organitzacio":"ecb org","foto":"igualada.png"}]
conn.setDoOutput(true);.
Remove that line. As you will not write data to the outputstream.
result.append(line);
That should be
result.append(line) + "\n";
For 'GET' connections set
conn.setDoOutput(false);
setDoOutput(true) is used for POST and PUT requests.

how read a Json file From a URL?

I wrote a program
I want download a json file from a URL and show it in a text view ..
When you click the button the program will stop after a few seconds .
I do not know what the problem is .
Please help me..
java code:
public class MainActivity extends Activity {
TextView tx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b=(Button)findViewById(R.id.button2);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new GetJsonTask().execute("http://shahid.ifilmtv.ir/query/englishcurrentshows");
}
});
}
public class GetJsonTask extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... urls) {
// TODO Auto-generated method stub
return getJson(urls[0]);
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
JSONArray jsonArray;
try {
jsonArray = new JSONArray(result);
JSONObject object = jsonArray.getJSONObject(1);
tx.setText(object.getString("id"));
}
catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public String getJson(String url) {
try {
InputStream inputStream = null;
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = defaultHttpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
inputStream = httpEntity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
inputStream.close();
String result = sb.toString();
return result;
} catch (Exception ex) {
Toast.makeText(getApplicationContext(), "ERROR : " + ex, Toast.LENGTH_LONG).show();
return null;
}
}
}
I think the issue is in getJSON method. I have rewritten a following code. Please try this.
public String getJson(String url) {
try {
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpost.setHeader("Accept", "application/json");
httpost.setHeader("Content-type", "application/json");
ResponseHandler responseHandler = new BasicResponseHandler();
Object resp = defaultHttpClient.execute(httpPost, responseHandler);
String json = resp.toString();
// create a object here if you want
JSONObject obj = new JSONObject(json);
return json;
} catch (Exception ex) {
Toast.makeText(getApplicationContext(), "ERROR : " + ex, Toast.LENGTH_LONG).show();
return null;
}
}

Receiving JSON java.lang.string cannot be converted to jsonarray

im making an app for a website. It has an JSON API. The URL im trying to fetch the result from is: http://api.bayfiles.net/v1/account/login/<user>/<password>
I get the error: java.lang.string cannot be converted to jsonarray when logging the error using logcat.
My main activity is:
public class MainActivity extends SherlockActivity {
EditText un,pw;
TextView error;
Button ok;
private ProgressDialog mDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
un = (EditText)findViewById(R.id.user);
pw = (EditText)findViewById(R.id.psw);
ok = (Button)findViewById(R.id.button1);
error = (TextView)findViewById(R.id.textView1);
ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//error.setText("Clicked");
//Intent startNewActivityOpen = new Intent(LoginActivity.this, FilesActivity.class);
//startActivityForResult(startNewActivityOpen, 0);
JsonAsync asyncTask = new JsonAsync();
// Using an anonymous interface to listen for objects when task
// completes.
asyncTask.setJsonListener(new JsonListener() {
public void onObjectReturn(JSONObject object) {
handleJsonObject(object);
}
});
// Show progress loader while accessing network, and start async task.
//mDialog = ProgressDialog.show(this, getSupportActionBar().getTitle(),
// getString(R.string.loading), true);
asyncTask.execute("http://api.bayfiles.net/v1/account/login/spxc/mess2005");
}
});
}
private void handleJsonObject(JSONObject object) {
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
try {
JSONArray shows = object.getJSONArray("error");
for (int i = 0; i < shows.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
JSONObject e = shows.getJSONObject(i);
//map.put("video_id", String.valueOf(i));
map.put("session", "" + e.getString("session"));
mylist.add(map);
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data: " + e.toString());
}
error.setText("session");
/*
//Intent myIntent = new Intent(ListMoviesController.this,
// TestVideoController.class);
myIntent.putExtra("video_title", o.get("video_title"));
myIntent.putExtra("video_channel", o.get("video_channel"));
myIntent.putExtra("video_location", o.get("video_location"));
startActivity(myIntent); */
}{
if (mDialog != null && mDialog.isShowing()) {
mDialog.dismiss();
}
}
}
And this is my adapter: JSONfunctions.java
public class JSONfunctions {
public static JSONObject getJSONfromURL(String url){
InputStream is = null;
String result = "";
JSONObject jArray = null;
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
try {
// Add your data
/*List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("key", "stianxxs"));
nameValuePairs.add(new BasicNameValuePair("secret", "mhfgpammv9f94ddayh8GSweji"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); */
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
//HttpResponse response = httpclient.execute(httppost);
HttpEntity httpEntity = response.getEntity();
is = httpEntity.getContent();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
try{
jArray = new JSONObject(result);
}catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return jArray;
}
}
Why im i getting this error? When using the right username and password in the url you would get: {"error":"","session":"RANDOM NUMBER"}
And as you can see i try to fetch this number. Any help is much appreciated!
You are getting this error because in line
JSONArray shows = object.getJSONArray("error");
you are trying to get value for key error and treat is as an array, whereas it's not - it's an empty string. Therefore you need to get it as a string:
String error = object.getString("error");
Similarly, if you need to get your "session", you can get it with
String session = object.getString("session");
P.S. Note that this is assuming that your JSONObject object actually contains the object represented by the string in your question.

APK file gets corrupted while writing to SD Card

I hit to a URL where my apk file is hosted and then write the bytes received to a file.
class DownloadAPKFile extends AsyncTask<String, Void, Boolean>{
private byte[] fileBytes;
#Override
protected Boolean doInBackground(String... params) {
Log.d("begin", "begun");
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet("http://www.website/Path/my.apk");
try {
HttpResponse response = client.execute(get);
Log.d("Login", "Response " + response.getEntity());
Log.d("Login", "contentLength " + response.getEntity().getContentLength());
String responseBody = EntityUtils.toString(response.getEntity());
fileBytes = responseBody.getBytes();
Log.d("fileBytes", "fileBytes");
String filePath = Environment.getExternalStorageDirectory() + "/myappdir/" + "my" + ".apk";
File file = new File(filePath);
file.getParentFile().mkdirs();
file.createNewFile();
BufferedOutputStream objectOut = new BufferedOutputStream(new FileOutputStream(file));
Log.d("objectOut", "objectOut");
objectOut.write(fileBytes);
Log.d("write", "write");
objectOut.close();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
This works like a charm, the problem i am having is that the content length from the entitiy is 582504 but when i look into the file manager the size goes upto 863145. I think that some data is being added while writing file to SD Card. Is there any solution to this?
This is my code which works fine, please check if this works for you
public class downloadApk extends AsyncTask<Integer, Integer, Integer>
{
#Override
protected Integer doInBackground(Integer... params) {
// TODO Auto-generated method stub
try {
URL url = new URL("http://www.tagsinfosoft.com/android/shelf/Shelf_Cam.apk");
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "Shelf_Cam.apk");
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();//till here, it works fine - .apk is download to my sdcard in download file
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Context context=shelf.this;
pd.dismiss();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "Shelf_Cam.apk")), "application/vnd.android.package-archive");
startActivity(intent);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd=ProgressDialog.show(shelf.this,"Updating","Please wait....." );
}
}

How to change listview items?

I'm getting strings from a HttpGet and I want to place them into the listview. How could I do this? I can't find any information on it anywhere. At the movement, I just have some test data in place.
Eg.
"Test1"
But I want it to be dynamic, from the strings the phone get's from the HttpGet.
Thanks.
My Code so far: (Apologies for the code being messy, I'll rewrite it soon!)
public class ChatService extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chatservice);
try {
ContactsandIm();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CheckLogin();
ListView list = (ListView) findViewById(R.id.ListView01);
list.setClickable(true);
final List<PhoneBook> listOfPhonebook = new ArrayList<PhoneBook>();
listOfPhonebook.add(new PhoneBook("a", "9981728", "test#test.com"));
listOfPhonebook
.add(new PhoneBook("Test1", "1234455", "test1#test.com"));
listOfPhonebook.add(new PhoneBook("Test2", "00000", "test2#test.com"));
PhonebookAdapter adapter = new PhonebookAdapter(this, listOfPhonebook);
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view,
int position, long index) {
System.out.println("sadsfsf");
showToast(listOfPhonebook.get(position).getName());
}
});
list.setAdapter(adapter);
}
private void CheckLogin() {
// TODO Auto-generated method stub
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
/* login.php returns true if username and password is equal to saranga */
HttpPost httppost = new HttpPost("http://gta5news.com/login.php");
try {
// Execute HTTP Post Request
Log.w("HttpPost", "Execute HTTP Post Request");
HttpResponse response = httpclient.execute(httppost);
String str = inputStreamToString(response.getEntity().getContent())
.toString();
Log.w("HttpPost", str);
if (str.toString().equalsIgnoreCase("true")) {
Log.w("HttpPost", "TRUE");
try {Thread.sleep(250);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//put intent here(21/3/12);
} else {
Log.w("HttpPost", "FALSE");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private StringBuilder inputStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// Read response until the end
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Return full string
return total;
}
private void ContactsandIm() throws URISyntaxException, ClientProtocolException, IOException {
// TODO Auto-generated method stub
BufferedReader in = null;
String data = null;
HttpClient get = new DefaultHttpClient();
URI website = new URI("http://www.gta5news.com/test.php");
HttpGet webget = new HttpGet();
webget.setURI(website);
HttpResponse response = get.execute(webget);
Log.w("HttpPost", "Execute HTTP Post Request");
in = new BufferedReader (new InputStreamReader(response.getEntity().getContent()));
//now we'll return the data that the PHP set from the MySQL Database.
// just some test code, to see if the HttpGet was working.
if (in.equals("True")); {
Toast.makeText(this,"yay", Toast.LENGTH_LONG).show();
}
}
// end bracket for "ContactsandIm"
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
From the code, i see that PhonebookAdapter is your custom adapter class. Why not parse the http response of type PhoneBook and add it to listOfPhonebook. That should show the parsed contents in the listView.
As I understand you need to add new PhoneBook entry every time your Http request is succeeded.
If so, you have to options to make everything dynamic:
Recreate adapter every time you receive new portion of data:
Make your listView global variable (to make it accessible from any function within the class)
Do the same with your List
Once you have received new portion of data - add this data to your List, create new adapter and set this adapter to your ListView
Create a custom adapter with possibility to update ListItems:
public class YourCustomAdapter extends BaseAdapter
{
private final LayoutInflater inflater;
private ArrayList list = new ArrayList();
private Handler uiHandler = new Handler();
/*..... default set of functions from BaseAdapter ......*/
public void setList(ArrayList<PhoneBook> list)
{
this.list = list;
}
public void addEntry(final PhoneBook entry)
{
uiHandler.post(new Runnable()
{
#Override
public void run()
{
list.add(entry);
YourCustomAdapter.notifyDataSetChanged();
}
});
}
}
please note that in this case you are allowed to modify underlying list ONLY from UI thread
Hope this helps

Categories

Resources