I've created an app which by clicking on a list Item, downloads an image from the Internet on a button click (also it places the url on to the EditText for user to see what the url is).
Initially I'm setting the ProgressBar and TextView (indicating Loading....) in a hide mode. But as the download starts, I would like to bring both TextView and ProgressBar on to the UI and once the download completes, would like to make both of them invisible.
There is NO error message on the LogCat to post. I believe I'm missing something which is tricky :). Let me know if any additional information is required. Thanks SO in advance.
Below is the XML: for LinearLayout which should be ON/OFF
<LinearLayout
android:id="#+id/loadingSection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/downloadImage"
android:visibility="gone"
android:orientation="vertical" >
<TextView
android:id="#+id/loadingMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Loading....."
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true" />
</LinearLayout>
And below is the Java file:
public class DownloadImages_HandlerMainActivity extends Activity implements OnItemClickListener {
private EditText editText;
private ListView listView;
private TextView textView;
private String[] listOfImages;
private Button downloadImage;
private ProgressBar progressBar;
private LinearLayout loadingSection = null;
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.downloadimages_main);
editText = (EditText) findViewById(R.id.downloadURL);
textView = (TextView) findViewById(R.id.loadingMessage);
listView = (ListView) findViewById(R.id.urlList);
downloadImage = (Button) findViewById(R.id.downloadImage);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
listOfImages = getResources().getStringArray(R.array.imageURLs);
listView.setOnItemClickListener(this);
handler = new Handler();
}
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position,
long id) {
editText.setText(listOfImages[position]);
}
public void downloadImage(View view) {
String url = editText.getText().toString();
Thread myThread = new Thread(new DownloadImagesThread(url));
myThread.start();
}
public boolean downloadImageUsingThreads(String url) {
boolean successful = false;
URL downloadURL = null;
HttpURLConnection connection = null;
InputStream inputStream = null;
File file = null;
FileOutputStream fileOutputStream = null;
try {
downloadURL = new URL(url);
connection = (HttpURLConnection) downloadURL.openConnection();
inputStream = connection.getInputStream();
file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).getAbsolutePath()
+ "/" + Uri.parse(url).getLastPathSegment());
fileOutputStream = new FileOutputStream(file);
int read = -1;
byte[] buffer = new byte[1024];
while ((read = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, read);
//Log.d("BRK0018", " " + read);
successful = true;
}
} catch (MalformedURLException e) {
e.printStackTrace();
Log.d("BRK0018", " " + e);
} catch (IOException e) {
e.printStackTrace();
Log.d("BRK0018", " " + e);
} finally {
// This is the HANDLER INSTANCE in place of thread
handler.post(new Runnable() {
#Override
public void run() {
try {
loadingSection.setVisibility(View.GONE); // Making the ProgressBar INVISIBLE
} catch (Exception e) {
Log.d("BRK0018", " " + e);
}
}
});
if (connection != null) {
connection.disconnect();
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
Log.d("BRK0018", " " + e);
}
}
}
return successful;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class DownloadImagesThread implements Runnable {
private String url;
public DownloadImagesThread(String url) {
this.url = url;
}
// This is the HANDLER INSTANCE in place of thread
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
try {
// TODO Auto-generated method stub
loadingSection.setVisibility(View.VISIBLE); // Making the ProgressBar VISIBLE
} catch (Exception e) {
Log.d("BRK0018", " " + e);
}
}
});
downloadImageUsingThreads(url);
}
}
}
The problem here is loadingSection which is null. And since you change its visibility in try/catch block, the app doesn't crash. Initialize the layout in onCreate():
loadingSection = (LinearLayout) findViewById(R.id.loadingSection);
First of all, when you call
handler.post(new Runnable() {
#Override
public void run() {
try {
// TODO Auto-generated method stub
loadingSection.setVisibility(View.VISIBLE);
Thread.sleep(1000);
} catch (Exception e) {
Log.d("BRK0018", " " + e);
}
}
});
Handler.class runs above code in UI thread.
You must not call Thread.sleep(1000) in UI thread.
(but anyway remember that loadingSection.setVisibility(View.VISIBLE); must be called in UI thread)
Fix it. And whether it helps or not write me.
Related
In the below code which is for bluetooth messaging with arduino i am trying to change color on some static strings.
1.On the start button listener i have a message"Connection opened" which i am changing color using the xml file and creating there a string with specific color. This method works only there.
2. i tried another method with spannable string on the send button listener but is not working at all the message comes in black.
what i want to to do is that when i send a message on my textview i see the "send data: "+ string(msg i send) and i want this send data to be red for examle and the same for the receive one.
What i tried untill now is on the code.If there is any idea to try i will be grateful.
public class MainActivity extends Activity {
private final UUID PORT_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");//Serial Port Service ID
private BluetoothDevice device;
private BluetoothSocket socket;
private OutputStream outputStream;
private InputStream inputStream;
Button startButton, sendButton,clearButton,stopButton;
TextView textView;
EditText editText;
boolean deviceConnected=false;
//Thread thread;
byte[] buffer;
//int bufferPosition;
boolean stopThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = findViewById(R.id.buttonStart);
sendButton = findViewById(R.id.buttonSend);
clearButton = findViewById(R.id.buttonClear);
stopButton = findViewById(R.id.buttonStop);
editText = findViewById(R.id.editText);
textView = findViewById(R.id.textView);
textView.setMovementMethod(new ScrollingMovementMethod());
setUiEnabled(false);
startButton.setOnClickListener(v -> {
if(BTinit())
{
if(BTconnect())
{
setUiEnabled(true);
deviceConnected=true;
beginListenForData();
//textView.append("Connection Opened!");
String greenString = getResources().getString(R.string.Connection_Opened);
textView.append(Html.fromHtml(greenString));
}
}
});
sendButton.setOnClickListener(v -> {
String t = "Send Data: ";
SpannableString spannableString = new SpannableString(t);
ForegroundColorSpan green = new ForegroundColorSpan(getResources().getColor(R.color.private_green));
spannableString.setSpan(green, 0, 9, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
String string = editText.getText().toString();
String str = string.concat("\n");
try {
outputStream.write(str.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
textView.append(spannableString + str);
});
stopButton.setOnClickListener(v -> {
try {
stopThread = true;
outputStream.close();
inputStream.close();
socket.close();
setUiEnabled(false);
deviceConnected=false;
textView.append("Connection Closed!");
}catch (IOException e){
e.printStackTrace();
}
});
clearButton.setOnClickListener(v -> textView.setText(""));
}
public void setUiEnabled(boolean bool)
{
startButton.setEnabled(!bool);
sendButton.setEnabled(bool);
stopButton.setEnabled(bool);
textView.setEnabled(bool);
}
public boolean BTinit()
{
boolean found=false;
BluetoothAdapter bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(getApplicationContext(),"Device doesnt Support Bluetooth",Toast.LENGTH_SHORT).show();
}
if(bluetoothAdapter !=null)
{
Intent enableAdapter = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableAdapter, 0);
}
assert bluetoothAdapter != null;
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
if(bondedDevices.isEmpty())
{
Toast.makeText(getApplicationContext(),"Please Pair the Device first",Toast.LENGTH_SHORT).show();
}
else
{
for (BluetoothDevice iterator : bondedDevices)
{
//private final String DEVICE_NAME="ArduinoBT";
String DEVICE_ADDRESS = "98:DA:C0:00:2C:E2";
if(iterator.getAddress().equals(DEVICE_ADDRESS))
{
device=iterator;
found=true;
break;
}
}
}
return found;
}
public boolean BTconnect()
{
boolean connected=true;
try {
socket = device.createRfcommSocketToServiceRecord(PORT_UUID);
socket.connect();
} catch (IOException e) {
e.printStackTrace();
connected=false;
}
if(connected)
{
try {
outputStream=socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream=socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
return connected;
}
void beginListenForData()
{
final Handler handler = new Handler();
stopThread = false;
buffer = new byte[1024];
Thread thread = new Thread(() -> {
while(!Thread.currentThread().isInterrupted() && !stopThread)
{
try
{
int byteCount = inputStream.available();
if(byteCount > 0)
{
byte[] rawBytes = new byte[byteCount];
inputStream.read(rawBytes);
final String string=new String(rawBytes, StandardCharsets.UTF_8);
handler.post(() -> textView.append("Receive data: " + string));
}
}
catch (IOException ex)
{
stopThread = true;
}
}
});
thread.start();
}
}
Try like this;
Spannable text = new SpannableString("Send Data:");
text.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.private_green)), 0, 9, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
I am creating a simple imageview with an id and trying to start an activity when it is clicked but when i click it in the emulator, the app just crashes and gives me (wait or close the app prompt)
here is my:
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:orientation="vertical">
<ImageView
android:id="#+id/about"
android:layout_width="match_parent"
android:layout_height="450dp"
android:background="#color/colorPrimaryDark"
android:src="#drawable/twoth" />
</LinearLayout>
and here is my java code
public class MainUi extends AppCompatActivity {
//Variables Declaration.
private Button btn1, btn2, btn3, btn4;
private ImageView img;
//Called when the activity is first created.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_ui);
//Variables Initialization and OnClick Method
img = (ImageView) findViewById(R.id.about);
img.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
//Start another activity
Intent myIntent = new Intent(MainUi.this, Query.class);
startActivity(myIntent);
}
});
}
}
The 'wait or close' thing leads me to think there's something in Query activity that is doing a lot of work on the main thread.
Try to use an AsyncTask and put all your long running processes in the doInBackground part and later handle the response in the onPostExecute.
I guess it depends a lot of what you are actually doing, but AsyncTask should be a good start.
here is the full code, I added the rest of the code just in case you can handle it from the outer (Query) class and not within Async Class.
public class Query extends AppCompatActivity {
private ArrayList<String[]> BB;
private ArrayList<String[]> AA = new ArrayList<String[]>();
private Socket socket = null;
private ObjectInputStream in = null;
private DataOutputStream out = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_query);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
try {
AA = new AsyncAction().execute().get();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
setTextViews();
}
}
public void setTextViews() {
View linearLayout = findViewById(R.id.info);
for (int y = 0; y < AA.size(); y++) {
// for (int x = 0; x < AA.get(0).length; x++) {}
TextView name = new TextView(this);
name.setText(AA.get(y)[0]);
name.setId(y);
name.setGravity(Gravity.CENTER);
name.setTextSize(30);
name.setPadding(0, 30, 0, 0);
name.setTextColor(this.getResources().getColor(R.color.icons));
name.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0));
ProgressBar pb = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal);
Drawable drawable = pb.getProgressDrawable();
drawable.setColorFilter(new LightingColorFilter(0xFF000000, this.getResources().getColor(R.color.colorPrimary)));
pb.setProgress(100);
final int finalY = y;
name.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Bundle b = new Bundle();
b.putStringArray("list", AA.get(finalY));
Intent i = new Intent(Query.this, Info.class);
i.putExtras(b);
startActivity(i);
}
});
((LinearLayout) linearLayout).addView(name);
((LinearLayout) linearLayout).addView(pb);
}
}
private class AsyncAction extends AsyncTask<String, Void, ArrayList> {
protected ArrayList doInBackground(String... args) {
try {
socket = new Socket(port, 8888);
out = new DataOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
// action
out.writeInt(2);
try {
in = new ObjectInputStream(socket.getInputStream());
BB = (ArrayList<String[]>) in.readObject();
in.close();
socket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
return BB;//returns what you want to pass to the onPostExecute()
}
protected void onPostExecute(ArrayList result) {
AA = result;
}
}
}
this is my first question and ive been stuck on this unknown problem for day now. The app was running successfully till i added some new code to make a custom listview component and to read some messages from the client.
The MainActivity.java
`public class MainActivity extends Activity {
TextView info, infoip, msg;
String message = "";
ServerSocket serverSocket;
ArrayList<String> list = new ArrayList<String>();
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
info = (TextView) findViewById(R.id.info);
infoip = (TextView) findViewById(R.id.infoip);
msg = (TextView) findViewById(R.id.msg);
//instantiate custom adapter
MyCustomAdapter adapter = new MyCustomAdapter(list, this);
//handle listview and assign adapter
ListView lView = (ListView)findViewById(R.id.myListView);
lView.setAdapter(adapter);
infoip.setText(getIpAddress());
Thread socketServerThread = new Thread(new SocketServerThread());
socketServerThread.start();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
public void addOrder(String ordername)
{
list.add(ordername);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.buzzer.ventern.clientservertrial/http/host/path")
);
AppIndex.AppIndexApi.start(client, viewAction);
}
#Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.buzzer.ventern.clientservertrial/http/host/path")
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}
public class SocketServerThread extends Thread {
String ordername;
static final int SocketServerPORT = 8080;
int count = 0;
MainActivity ma= new MainActivity();
#Override
public void run() {
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
info.setText("I'm waiting here: "
+ serverSocket.getLocalPort());
}
});
while (true) {
socket = serverSocket.accept();
dataInputStream = new DataInputStream(
socket.getInputStream());
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
String messageFromClient = "";
//If no message sent from client, this code will block the program
messageFromClient = dataInputStream.readUTF();
ordername=dataInputStream.readUTF();
ma.addOrder(ordername);
count++;
message += "#" + count + " from " + socket.getInetAddress()
+ ":" + socket.getPort() + "\n"
+ "Msg from client: " + messageFromClient + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(message);
}
});
String msgReply = "Hello from server, order #" + count+" has been accepted.";
dataOutputStream.writeUTF(msgReply);
dataOutputStream.flush();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
final String errMsg = e.toString();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(errMsg);
}
});
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
}`
The MyCustomAdapter
public class MyCustomAdapter extends BaseAdapter implements ListAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Context context;
public MyCustomAdapter(ArrayList<String> list, Context context) {
this.list = list;
this.context = context;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
#Override
public long getItemId(int pos) {
return 0;
//just return 0 if your list items do not have an Id variable.
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.layout_list_item, null);
}
//Handle TextView and display string from your list
TextView listItemText = (TextView)view.findViewById(R.id.list_item_string);
listItemText.setText(list.get(position));
//Handle buttons and add onClickListeners
Button deleteBtn = (Button)view.findViewById(R.id.delete_btn);
deleteBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
//send acknowledgement to client
list.remove(position); //or some other task
notifyDataSetChanged();
}
});
return view;
}
}
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="Server V1.0"
android:textStyle="bold" />
<TextView
android:id="#+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/infoip"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="255dp" >
<TextView
android:id="#+id/msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/myListView"
android:layout_gravity="center_horizontal" />
ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:clickable="true"
android:contextClickable="false" />
</LinearLayout>
and the layout_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/list_item_string"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:paddingLeft="8dp"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="#+id/delete_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:text="Okay" />
</RelativeLayout>
I am new to android, and alot of this code is referenced from some android-er posts and some from previous stackoverflow answers. If anyone could tell me why my app crashes when started.
EDIT: Solved the error, but now exception in ASyncTAsk in the client, in doInBackground()
code of the doInBackground() of the client app
protected Void doInBackground(Void... arg0) {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket(dstAddress, dstPort);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
item=ma.getStr();
dataOutputStream.writeUTF(item);
dataOutputStream.flush();
response = dataInputStream.readUTF();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}`
I'm encountering a problem, when I try running an asynchronous task on refresh using a swipe refresh layout it "freezes" and doesn't rotate. When the task is done it just disappears.
Here is my code:
HotActivityFragment.java:
public class HotActivityFragment extends Fragment {
ListView hotList;
SwipeRefreshLayout mSwipeRefreshLayout;
Context context;
SharedPreferences sharedPreferences;
HotListAdapter hotListAdapter;
public HotActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_hot, container, false);
context = getContext();
mSwipeRefreshLayout = (SwipeRefreshLayout)view.findViewById(R.id.activity_main_swipe_refresh_layout);
hotList = (ListView)view.findViewById(R.id.hotListView);
hotList.setOnScrollListener(new EndlessScrollListener(getActivity()));
sharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
try {
ArrayList<ListTypeItem> initial_list = new DownloadPosts(getActivity()).execute().get();
this.hotListAdapter = new HotListAdapter(getContext(), initial_list);
hotList.setAdapter(hotListAdapter);
}catch(Exception e)
{
Log.d("Download Error", e.toString());
}
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
retrievePosts();
}
});
mSwipeRefreshLayout.setColorSchemeResources(R.color.accentColor, R.color.backgroundColor);
return view;
}
public void retrievePosts()
{
// showing refresh animation before making http call
mSwipeRefreshLayout.setRefreshing(true);
//shared preferences = empty
sharedPreferences.edit().putString("last_time_downloaded", "empty").commit();
try {
ArrayList<ListTypeItem> listItems = new DownloadPosts(getActivity(), mSwipeRefreshLayout).execute().get();
hotListAdapter.updateList(listItems);
hotListAdapter.notifyDataSetChanged();
} catch (Exception e) {
Log.d("Download Error", e.toString());
}
mSwipeRefreshLayout.setRefreshing(false);
//for testing purposes
// new Handler().postDelayed(new Runnable() {
// #Override public void run() {
// mSwipeRefreshLayout.setRefreshing(false);
// }
// }, 5000);
}
}
DownloadPosts.java:
public class DownloadPosts extends AsyncTask<Void, Void, ArrayList<ListTypeItem>> {
SharedPreferences sharedPreferences;
SwipeRefreshLayout swipeRefreshLayout;
public DownloadPosts(Activity activity)
{
this.sharedPreferences = activity.getPreferences(Context.MODE_PRIVATE);
}
public DownloadPosts(Activity activity, SwipeRefreshLayout swipeRefreshLayout)
{
this.sharedPreferences = activity.getPreferences(Context.MODE_PRIVATE);
this.swipeRefreshLayout = swipeRefreshLayout;
}
#Override
protected ArrayList<ListTypeItem> doInBackground(Void... args)
{
StringBuilder parsedString = new StringBuilder();
ArrayList<ListTypeItem> downloadList = new ArrayList<>();
StringBuilder str = new StringBuilder();
if(sharedPreferences.getBoolean("Thomas More",false))
{
str.append("190155257998823,");
}
String school_url = str.toString();
if(school_url.length() > 0)
{
school_url = school_url.substring(0, str.length()-1);
}
try{
String date = "";
//checken of opnieuw moet bepaald worden
// + in de adapter moet als gereload wordt last_time_downloaded == empty
if(!sharedPreferences.getString("last_time_downloaded","empty").equals("empty"))
{
String last_date = sharedPreferences.getString("last_time_downloaded","nothing");
last_date = last_date.replace(" ","T");
date= "&datum_last_posted=" + last_date;
}
URL url = new URL("http://localhost/getpostlist.php?school_post=" + school_url + date);
URLConnection conn = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String json;
while((json = bufferedReader.readLine())!= null)
{
parsedString.append(json + "/n");
}
String s = parsedString.toString().trim();
//converten van string opgehaald via http naar jsonobject
JSONArray array = new JSONArray(s);
for(int i = 0; i < array.length(); i++)
{
JSONObject tempObj = array.getJSONObject(i);
School_WithoutImage tempSchool = new School_WithoutImage(tempObj.getString("school_id"),
tempObj.getString("post_message"),tempObj.getInt("views"),tempObj.getInt("likes")
,tempObj.getInt("post_id"),tempObj.getString("datum_posted"));
downloadList.add(tempSchool);
if(i == array.length()-1) {
sharedPreferences.edit().putString("last_time_downloaded",tempObj.getString("datum_posted")).commit();
}
}
JSONObject obj = array.getJSONObject(0);
}catch(Exception e)
{
Log.d("Exception", e.toString());
}
return downloadList;
}
#Override
protected void onPostExecute(ArrayList<ListTypeItem> result)
{
if(this.swipeRefreshLayout != null)
{
// swipeRefreshLayout.setRefreshing(false);
}
}
}
I have no idea why the swiperefreshview doesn't spin. Anyone has an idea?
Because the call to get():
.execute().get()
Forces the UI thread to wait for the AsyncTask to finish.
Instead you should look at doing this in the onPostExecute method:
protected void onPostExecute(ArrayList<ListTypeItem> listItems) {
hotListAdapter.updateList(listItems);
hotListAdapter.notifyDataSetChanged();
}
Because you are waiting for the result from asynctask by calling get just after execute. And further passing it to list.
You can use Local Broadcast Listener or can create an interface and can us that as callback, without freezing UI
I'm programming a code to open my room's door. But I have an issue.
The TextView.setText does not keep the new String I can see the String changed when the system ask to the user if allow enable Bluetooth textViewBluetooth.setText works, but when the bluetooth is enabled the textViewBluetooth returns to the original String setted on activity_main.xml and I never see it update again even setting text on an special button.
I already debug my code, i can see the setText called in TextView but still have no update string.
I try to add a new TextView but I get the same issue in both TextView.
I comment the bluetoothThread class but the problem persist.
Thanks for your time.
public class MainActivity extends ActionBarActivity {
private static final int REQUEST_ENABLE_BT = 1;
private static final int RESULT_SETTINGS = 1;
private BluetoothAdapter mBTadapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice>pairedDevices;
private BluetoothThread mBluetoothThread = null;
final String deviceAddress = "98:D3:31:20:0B:C9";
String SN = null;
TextView textViewBluetooth;
ImageView imageViewBT;
ImageView imageViewAbrir;
ImageView imageViewCerrar;
boolean NewDevice = false;
ArrayList listNoBondedDevices = new ArrayList();
ArrayAdapter<String> mNewDevicesArrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewBluetooth = (TextView) findViewById(R.id.textView01);
imageViewBT = (ImageView) findViewById(R.id.imageViewBT);
imageViewAbrir = (ImageView) findViewById(R.id.imageViewAbrir);
imageViewCerrar = (ImageView) findViewById(R.id.imageViewCerrar);
mNewDevicesArrayAdapter = new ArrayAdapter<String>
(this,android.R.layout.simple_list_item_1,listNoBondedDevices);
registerReceiver(mReceiver,new IntentFilter(BluetoothDevice.ACTION_FOUND));
mBluetoothThread = new BluetoothThread();
}
#Override
protected void onResume(){
super.onResume();
if(mBTadapter.isEnabled()){
if(!mBluetoothThread.btSocketConnected) {
setContentView(R.layout.activity_main);
tryConnectBTdevice(deviceAddress);
}
}
else {
intentEnableBT();
}
}
void intentEnableBT(){
textViewBluetooth.setText("Encendiendo bluetooth");
Intent intentEnableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intentEnableBT, REQUEST_ENABLE_BT);
}
void tryConnectBTdevice(String address){
if(address != null && address != "00:00:00:00:00:00") {
BluetoothDevice mBTdevice = mBTadapter.getRemoteDevice(address);
if (!mBluetoothThread.btSocketConnected) {
textViewBluetooth.setText("Conectando a\n" + address.toString());
mBluetoothThread.connect(mBTdevice);
}
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode){
case REQUEST_ENABLE_BT:
if(resultCode == Activity.RESULT_OK){
textViewBluetooth.setText("Bluetooth encendido");
tryConnectBTdevice(deviceAddress);
}
else if(resultCode == Activity.RESULT_CANCELED){
textViewBluetooth.setText("No se logró encender Bluetooth");
}
break;
}
}
}
My BluetoothThread:
public class BluetoothThread {
boolean bconnectedthread = false;
boolean bconnectthread = false;
boolean bconnectthreadstart = false;
boolean brun = false;
boolean bconnectedsynchronized = false;
boolean btSocketConnected = false;
private BluetoothAdapter mBluetoothAdapter = null;
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private ConnectedThread mConnectedThread;
private ConnectThread mConnectThread;
public void write(byte[] out) {
ConnectedThread r;
synchronized (this) {
r = mConnectedThread;
}
r.write(out);
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
bconnectthread = true;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.cancelDiscovery();
brun=true;
try {
mmSocket.connect();
btSocketConnected = true;
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
connected(mmSocket);
}
public void cancel() {
try {
mmSocket.close();
btSocketConnected = false;
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public Handler mHandler = null;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
bconnectedthread = true;
Message message;
Handler mHandler;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes; // bytes returned from read()
while (true) {
try {
bytes = mmInStream.read(buffer);
//mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
// .sendToTarget();
} catch (IOException e) {
break;
}
}
}
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
public void disconnectDevice() {
if (mmSocket.isConnected()) {
try {
mmSocket.close();
btSocketConnected = false;
} catch (IOException e) {
}
}
}
}
public synchronized void disconnect(){
mConnectedThread.disconnectDevice();
}
public synchronized void connect(BluetoothDevice device)
{
bconnectthreadstart=true;
mConnectThread = new ConnectThread(device);
mConnectThread.start();
}
public synchronized void connected(BluetoothSocket socket) {
bconnectedsynchronized=true;
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
}
}
My activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.automovil.app.MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageViewBT"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#drawable/bluetooth"
android:onClick="onSyncBT" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/textView01"
android:layout_below="#+id/imageViewBT"
android:layout_centerHorizontal="true"
android:layout_marginTop="39dp"
android:textColor="#00026a"
android:text="Bluetooth"
android:enabled="true"
android:editable="false"
android:clickable="false"
android:autoText="false"
android:autoLink="none" />
</RelativeLayout>
Sorry for my English grammar :\
Thanks a lot for your time again.
Abraham Jaime
You're calling 'setContentView' in onResume. Call that in onCreate.
onActivityResult is called BEFORE onResume, and you're doing your own multithreading here, which can be rough. Especially in this case.
tryConnectBTdevice is called from onActivityResult, which then starts a thread, but 99% of the time you'll probably wind up in in onResume before all of that happens, which means your code calls setContentView again, AND tryConnectBTdevice again.
You're referencing boolean primitives from multiple threads to check for status, which isn't great. Should probably use AtomicBoolean, but that's probably not a huge issue.
What would get a long talk from me if we were working together is eating your IOException's. Error control is very important. Those are being thrown for a reason. Its probably blowing up because you're already connected, which would've tipped you off to the double-call situation.
Simple answer, assuming you're going to ignore all my warnings about exceptions. Don't call setContentView in onResume, and don't call tryConnectBTdevice in onActivityResult, because you're calling it from onResume anyway.
If this is for your room, OK. If you're making a product, I'd strongly advise a rewrite of the threading code.