I have used a tutorial and arrived at this result which works in an emulator, but it ceases to work on a real Android device.
The code is given here and all other Android permissions required are set; internet and write to external device are set.
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import org.apache.http.util.ByteArrayBuffer;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
public class main extends Activity {
private final String PATH = "/mnt/sdcard/Pictures/";
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.textView1);
DownloadFromUrl(PATH + "dwnldimg.png");
ImageView iv = (ImageView) findViewById(R.id.imageView1);
Bitmap bmp = BitmapFactory.decodeFile(PATH + "dwnldimg.png");
iv.setImageBitmap(bmp);
}
public void DownloadFromUrl(String fileName) {
try {
URL url = new URL("http://192.168.1.4/evilempire.jpg"); //you can write here any link
File file = new File(fileName);
long startTime = System.currentTimeMillis();
tv.setText("Starting download......from " + url);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();;
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
/*
* Read bytes to the Buffer until there is nothing more to read(-1).
*/
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.close();
tv.setText("Download Completed in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
} catch (IOException e) {
tv.setText("Error: " + e);
}
}
}
Prime lib will help you, but to learn Android you need to know AsyncTask. Android have the UI Thread where the Activity runs, so if you do complicate operation that block the Android OS will throw a Force Close.
So what you have to know is that if you need to do a download task or any operation that will eventually block the UI thread you can have to use Threads. The easy Android approach is AsyncTask.
I think this simple example will guide you to understand the AsyncTask.
http://developer.android.com/reference/android/os/AsyncTask.html
First of all your doing network operations on the main ui thread, which will result in a anr on pre-3.0 and a NetworkOnMainThreadException on 3.0+. Secondly I built Prime which is a whole lot easier at loading remote images.
Related
I'm a newbie in Android Development. I want to get metadata from Shoutcast Server, and found streamscraper to be the easiest one to use. But my problem is, I don't know how to use it. The homepage itself only showing something like in how to use it:
import java.net.URI;
import java.util.List;
import net.moraleboost.streamscraper.Stream;
import net.moraleboost.streamscraper.Scraper;
import net.moraleboost.streamscraper.scraper.IceCastScraper;
public class Harvester {
public static void main(String[] args) throws Exception {
Scraper scraper = new IceCastScraper();
List streams = scraper.scrape(new URI("http://host:port/"));
for (Stream stream: streams) {
System.out.println("Song Title: " + stream.getCurrentSong());
System.out.println("URI: " + stream.getUri());
}
}
}
Searched anywhere and found no project sample of how to use this. I hope one of you can post the code of how to use it, or make a tutorial for it.
No need to use external libraries. The following pages give you:
Current song: http://yourstream:port/currentsong?sid=#
Last 20 songs: http://yourstream:port/played.html?sid#
Next songs: http://yourstream:port/nextsongs?sid=#
An Android java class which prints the current song:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
public class NowPlaying {
public void CurrentSong() {
try
{
URL url = new URL("http://www.mofosounds.com:8000/currentsong?sid=#");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
}
Note: the nextsongs?sid=#feature must be supported by the player of the stream.
I'm trying to serve a small file on my desktop using NanoHTTPD. The server starts fine but due to some unknown reason, it is unable to serve files. The same program works fine in Android. Can anyone give me some pointers? It's being more than an hour but I've got no clue. Here is my desktop version of NanoHTTPD server:
package com.desktopserver;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLConnection;
import java.util.Map;
import com.desktopserver.NanoHTTPD.Response.Status;
public class MainClass {
static int PORT = 8080;
static WebServer MyServer;
static FileInputStream fis;
static BufferedInputStream bis;
public static void main(String[] args) {
MyServer = new WebServer();
try {
MyServer.start();
System.out.println("Webserver Started # PORT:8080");
} catch (IOException e) {
e.printStackTrace();
}
}
public static class WebServer extends NanoHTTPD {
String MIME_TYPE;
public WebServer() {
super(PORT);
}
#Override
public Response serve(String uri, Method method,
Map<String, String> header, Map<String, String> parameters,
Map<String, String> files) {
try {
File file=new File("/home/evinish/Music/Meant_to_live.mp3");
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
MIME_TYPE= URLConnection.guessContentTypeFromName(file.getName());
System.out.println("\nMIME TYPE: "+MIME_TYPE);
System.out.println("\nFILE NAME: "+file.getName());
} catch (IOException ioe) {
System.out.println("File IO Exception");
}
return new NanoHTTPD.Response(Status.OK, MIME_TYPE, bis);
}
}
}
I do get this output, but that's it:
Webserver Started # PORT:8080
What am I missing here? Thanks a lot for your help.
Because you don't use "ServerRunner" class. ServerRunner hold you server to until any key press.
But in real application this don't work you want some change in NanoHTTPd file
line no 196 to
myThread.setDaemon(false);
I am trying to test this bluetooth communication example between a PC and an Android phone. My SPP client is exactly the one from there and it works fine. I am new to Android and I didn't want to make it run in a separate thread because I don't know how, so I just did everything in the onCreate() method. If this is not the best way, feel free to point me to a better way, but this is not my main problem.
The problem is I wanted to display the text received via bluetooth on a textView and I don't know how to read from InputStream. When the code is left like that, it displays something like java.io.DataInputStream#41b0cb68
I tried it like here it didn't display anything, also I don't know what encoding is being used.
here's my android app's code:
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.*;
import android.util.Log;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
//based on java.util.UUID
private static UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");
// The local server socket
private BluetoothServerSocket mmServerSocket;
// based on android.bluetooth.BluetoothAdapter
private BluetoothAdapter mAdapter;
private BluetoothDevice remoteDevice;
TextView text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.textView_Text);
BluetoothSocket socket = null;
mAdapter = BluetoothAdapter.getDefaultAdapter();
// Listen to the server socket if we're not connected
// while (true) {
try {
// Create a new listening server socket
Log.d((String) this.getTitle(), ".....Initializing RFCOMM SERVER....");
// MY_UUID is the UUID you want to use for communication
mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("MyService", MY_UUID);
//mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID); // you can also try using In Secure connection...
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (Exception e) {
}
try {
Log.d((String) this.getTitle(), "Closing Server Socket.....");
mmServerSocket.close();
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
DataInputStream mmInStream = new DataInputStream(tmpIn);
DataOutputStream mmOutStream = new DataOutputStream(tmpOut);
// here you can use the Input Stream to take the string from the client whoever is connecting
//similarly use the output stream to send the data to the client
text.setText(mmInStream.toString());
} catch (Exception e) {
//catch your exception here
}
// }
}
}
I commented out the while(true) loop because I think it was making my app crash when onPause() was being called. I know this is not the best implementation but I really want to read from the bluetooth I feel like I am very close :), other aspects will be dealt with afterwards (like working with threads and so on).
I finally managed to correctly display in a TextView the string sent from the PC ("Test String from SPP Client\r\n").
I used this question, namely this piece of code, just below DataOutputStream mmOutStream = new DataOutputStream(tmpOut);:
// Read from the InputStream
bytes = mmInStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity
This is a very rudimentary example, designed only to show how to display strings received via bluetooth on the screen of the device. It is not done in a separate thread, and after it receives the string you have to close the app and restart it again, but the main purpose of the app was achieved (as I stated when I asked this question). What I really, really wanted was to receive a string from PC and display it on screen.
Here's my complete MainActivity, if somebody wants me to post a more complete approach (like using a separate thread) I will post it here once I complete it.
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.*;
import android.util.Log;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
//based on java.util.UUID
private static UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");
// The local server socket
private BluetoothServerSocket mmServerSocket;
// based on android.bluetooth.BluetoothAdapter
private BluetoothAdapter mAdapter;
private BluetoothDevice remoteDevice;
TextView text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.textView_Text);
BluetoothSocket socket = null;
mAdapter = BluetoothAdapter.getDefaultAdapter();
// Listen to the server socket if we're not connected
// while (true) {
try {
// Create a new listening server socket
Log.d((String) this.getTitle(), ".....Initializing RFCOMM SERVER....");
// MY_UUID is the UUID you want to use for communication
mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("MyService", MY_UUID);
//mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID); // you can also try using In Secure connection...
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (Exception e) {
}
byte[] buffer = new byte[256]; // buffer store for the stream
int bytes; // bytes returned from read()
try {
Log.d((String) this.getTitle(), "Closing Server Socket.....");
mmServerSocket.close();
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
DataInputStream mmInStream = new DataInputStream(tmpIn);
DataOutputStream mmOutStream = new DataOutputStream(tmpOut);
// here you can use the Input Stream to take the string from the client whoever is connecting
//similarly use the output stream to send the data to the client
// Read from the InputStream
bytes = mmInStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity
text.setText(readMessage);
} catch (Exception e) {
//catch your exception here
}
// }
}
}
Any questions? :)
Basically, you'll need to match the way data is sent from one device to the way data is received by the other one.
SPP is stream based and transfers bytes of data. So, whatever bytes the sending device transmits must be interpreted correctly by the receiver.
An InputStream gives you access to the raw bytes transmitted, and you'll have to do something with them; i.e. decode them in some way as needed. For instance, if the sender uses an ObjectOutputStream to do the encoding prior to transmission, the receiver will have to use an ObjectInputStream to decode the input.
You may want to read up on InputStream (read()), ObjectInputStream, and toString().
Besides, reading from a blocking stream should almost always be done in a separate thread; and especially so when reading from some remote device/host/network/... with possible unknown delays or transmission speed.
This question already has answers here:
How do I obtain crash-data from my Android application?
(30 answers)
Closed 5 months ago.
I'm currently developing an android app. I noticed a very rare error which leeds to a crash of my app. Unfortunately, I had my smartphone never connected to my pc when it occured. So, is there a way to automatically save all logs (and especially the thrown runtimeexceptions) to a file when my app starts, so that I can copy this file to my pc and analyse the error? The file should be overwritten on every start of my app, so that it contains only the logs of the last run... How can I achieve that?
regards
You can find help by following this link Writing crash reports into device sd card
You don't need to add external library.
import com.wordpress.doandroid.Training.R;
import android.app.Activity;
import android.os.Bundle;
public class CaptureExceptionActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Sets the default uncaught exception handler. This handler is invoked
// in case any Thread dies due to an unhandled exception.
Thread.setDefaultUncaughtExceptionHandler(new CustomizedExceptionHandler(
"/mnt/sdcard/"));
String nullString = null;
System.out.println(nullString.toString());
setContentView(R.layout.main);
}
}
And the Handler implementation
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.os.Environment;
import android.util.Log;
public class CustomizedExceptionHandler implements UncaughtExceptionHandler {
private UncaughtExceptionHandler defaultUEH;
private String localPath;
public CustomizedExceptionHandler(String localPath) {
this.localPath = localPath;
//Getting the the default exception handler
//that's executed when uncaught exception terminates a thread
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
public void uncaughtException(Thread t, Throwable e) {
//Write a printable representation of this Throwable
//The StringWriter gives the lock used to synchronize access to this writer.
final Writer stringBuffSync = new StringWriter();
final PrintWriter printWriter = new PrintWriter(stringBuffSync);
e.printStackTrace(printWriter);
String stacktrace = stringBuffSync.toString();
printWriter.close();
if (localPath != null) {
writeToFile(stacktrace);
}
//Used only to prevent from any code getting executed.
// Not needed in this example
defaultUEH.uncaughtException(t, e);
}
private void writeToFile(String currentStacktrace) {
try {
//Gets the Android external storage directory & Create new folder Crash_Reports
File dir = new File(Environment.getExternalStorageDirectory(),
"Crash_Reports");
if (!dir.exists()) {
dir.mkdirs();
}
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy_MM_dd_HH_mm_ss");
Date date = new Date();
String filename = dateFormat.format(date) + ".STACKTRACE";
// Write the file into the folder
File reportFile = new File(dir, filename);
FileWriter fileWriter = new FileWriter(reportFile);
fileWriter.append(currentStacktrace);
fileWriter.flush();
fileWriter.close();
} catch (Exception e) {
Log.e("ExceptionHandler", e.getMessage());
}
}
}
Don't forget to add this permission in the manifest WRITE_EXTERNAL_STORAGE
I found a snippet online for showing a download's progress. The error I'm getting is android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. My goal is to have the phone download a file and then when completed, switch to the chaptermenu intent
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;
public class CheckDownload extends Activity {
/** Called when the activity is first created. */
#Override
protected void onCreate(Bundle SavedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(SavedInstanceState);
setContentView(R.layout.downloadscreen);
Thread timer = new Thread() {
public void run() {
try {
// set the download URL, a url that points to a file on the
// internet
// this is the file to be downloaded
URL url = new URL(
"http://www.android.com/media/wallpaper/gif/android_logo.gif");
// create the new connection
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
// set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
// and connect!
urlConnection.connect();
// set the path where we want to save the file
// in this case, going to save it on the root directory of
// the
// sd card.
File SDCardRoot = Environment.getExternalStorageDirectory();
// create a new file, specifying the path, and the filename
// which we want to save the file as.
File file = new File(SDCardRoot, "android_logo.gif");
// this will be used to write the downloaded data into the
// file we created
FileOutputStream fileOutput = new FileOutputStream(file);
// this will be used in reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
// this is the total size of the file
int totalSize = urlConnection.getContentLength();
// variable to store total downloaded bytes
int downloadedSize = 0;
// create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0; // used to store a temporary size of
// the buffer
// now, read through the input buffer and write the contents
// to the file
while ((bufferLength = inputStream.read(buffer)) > 0) {
// add the data in the buffer to the file in the file
// output stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
// add up the size so we know how much is downloaded
downloadedSize += bufferLength;
// this is where you would do something to report the
// prgress, like this maybe
updateProgress(downloadedSize, totalSize);
}
// close the output stream when done
fileOutput.close();
// catch some possible errors...
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
Intent chapterMenuIntentObject = new Intent(
"com.blah.blah.CHAPTERMENU");
startActivity(chapterMenuIntentObject);
}
}
};
timer.start();
}
public void updateProgress(int downloadedSize, int totalSize) {
int percentage = downloadedSize / totalSize * 100;
String stringy = "Download Progress: " + percentage + "%";
TextView textytext = (TextView) findViewById(R.id.downloadscreentextview);
textytext.setText(stringy);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
finish();
}
}
One easier way to do this is to use runOnUIThread(Runnable) function. This is a function of Activity class for updating UI. I find using it more convenient than creating handlers/messages for communicating with UI thread. Your code can be changed to (I have not test yet!):
public void updateProgress(int downloadedSize, int totalSize) {
runOnUiThread(new Runnable() {
public void run() {
int percentage = downloadedSize / totalSize * 100;
String stringy = "Download Progress: " + percentage + "%";
TextView textytext = (TextView) findViewById(R.id.downloadscreentextview);
textytext.setText(stringy);
}});
}
Let me know if you have any error.
You are trying to update the progress from worker(or background thread) where it doesnot get reference to your views. It has to be done on UI thread.
Try using AsynTask , makes life easier with threads.
http://developer.android.com/reference/android/os/AsyncTask.html
or
if you want to stick with normal threads,
Check this code,
http://huuah.com/android-progress-bar-and-thread-updating/
You might have to use messageHandler to send message to progressbar, and then update.