I am presently working on program on Android Things for connecting to Google Cloud IoT Core. I used to sample maven code provided by Google and modified it for Gradle(with all the imports and stuff). After doing every kind of check, whenever I am trying to run the program on a Raspberry Pi3 running Android Things it keeps giving this error
W/System.err: java.io.FileNotFoundException: com/example/adityaprakash/test/rsa_private.pem (No such file or directory)
telling me that the private key file that I am supposed to use for the JWT doesn't exist despite the fact it does and I have given the path for the pem file.Here are my java codes
package com.example.adityaprakash.test;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
Log.i("#########","######");
MqttExample mqtt = new MqttExample();
try {
mqtt.Start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The MqttExample.java
package com.example.adityaprakash.test;
// [END cloudiotcore_mqtt_imports]
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.joda.time.DateTime;
import java.io.BufferedReader;
import java.io.FileReader;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import android.util.Base64;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
public class MqttExample {
// [START cloudiotcore_mqtt_createjwt]
/** Create a Cloud IoT Core JWT for the given project id, signed with the given RSA key. */
public static String createJwtRsa(String projectId, String privateKeyFile) throws Exception {
DateTime now = new DateTime();
String strKeyPEM = "";
BufferedReader br = new BufferedReader(new FileReader(privateKeyFile));
String line;
while ((line = br.readLine()) != null) {
strKeyPEM += line + "\n";
}
br.close();
// Create a JWT to authenticate this device. The device will be disconnected after the token
// expires, and will have to reconnect with a new token. The audience field should always be set
// to the GCP project id.
JwtBuilder jwtBuilder =
Jwts.builder()
.setIssuedAt(now.toDate())
.setExpiration(now.plusMinutes(20).toDate())
.setAudience(projectId);
String privateKeyPEM = strKeyPEM;
privateKeyPEM = privateKeyPEM.replace("-----BEGIN PRIVATE KEY-----\n", "");
privateKeyPEM = privateKeyPEM.replace("-----END PRIVATE KEY-----", "");
byte[] encoded = Base64.decode(privateKeyPEM,Base64.DEFAULT);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
return jwtBuilder.signWith(SignatureAlgorithm.RS256, kf.generatePrivate(spec)).compact();
}
/** Parse arguments, configure MQTT, and publish messages. */
public void Start() throws Exception {
// [START cloudiotcore_mqtt_configuremqtt]
MqttExampleOptions options = MqttExampleOptions.values();
if (options == null) {
// Could not parse.
System.exit(1);
}
// Build the connection string for Google's Cloud IoT Core MQTT server. Only SSL
// connections are accepted. For server authentication, the JVM's root certificates
// are used.
final String mqttServerAddress =
String.format("ssl://%s:%s", options.mqttBridgeHostname, options.mqttBridgePort);
// Create our MQTT client. The mqttClientId is a unique string that identifies this device. For
// Google Cloud IoT Core, it must be in the format below.
final String mqttClientId =
String.format(
"projects/%s/locations/%s/registries/%s/devices/%s",
options.projectId, options.cloudRegion, options.registryId, options.deviceId);
MqttConnectOptions connectOptions = new MqttConnectOptions();
// Note that the the Google Cloud IoT Core only supports MQTT 3.1.1, and Paho requires that we
// explictly set this. If you don't set MQTT version, the server will immediately close its
// connection to your device.
connectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
// With Google Cloud IoT Core, the username field is ignored, however it must be set for the
// Paho client library to send the password field. The password field is used to transmit a JWT
// to authorize the device.
connectOptions.setUserName("unused");
System.out.println(options.algorithm);
if (options.algorithm.equals("RS256")) {
connectOptions.setPassword(
createJwtRsa(options.projectId, options.privateKeyFile).toCharArray());
}else {
throw new IllegalArgumentException(
"Invalid algorithm " + options.algorithm + ". Should be one of 'RS256' or 'ES256'.");
}
// [END cloudiotcore_mqtt_configuremqtt]
// [START cloudiotcore_mqtt_publish]
// Create a client, and connect to the Google MQTT bridge.
MqttClient client = new MqttClient(mqttServerAddress, mqttClientId, new MemoryPersistence());
try {
client.connect(connectOptions);
// Publish to the events or state topic based on the flag.
String subTopic = options.messageType.equals("event") ? "events" : options.messageType;
// The MQTT topic that this device will publish telemetry data to. The MQTT topic name is
// required to be in the format below. Note that this is not the same as the device registry's
// Cloud Pub/Sub topic.
String mqttTopic = String.format("/devices/%s/%s", options.deviceId, subTopic);
// Publish numMessages messages to the MQTT bridge, at a rate of 1 per second.
for (int i = 1; i <= options.numMessages; ++i) {
String payload = String.format("%s/%s-payload number-%d", options.registryId, options.deviceId, i);
System.out.format(
"Publishing %s message %d/%d: '%s'\n",
options.messageType, i, options.numMessages, payload);
// Publish "payload" to the MQTT topic. qos=1 means at least once delivery. Cloud IoT Core
// also supports qos=0 for at most once delivery.
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(1);
client.publish(mqttTopic, message);
if (options.messageType.equals("event")) {
// Send telemetry events every second
Thread.sleep(1000);
}
else {
// Note: Update Device state less frequently than with telemetry events
Thread.sleep(5000);
}
}
} finally {
// Disconnect the client and finish the run.
client.disconnect();
}
System.out.println("Finished loop successfully. Goodbye!");
// [END cloudiotcore_mqtt_publish]
}
}
and the MqttExampleOptions.java code:
package com.example.adityaprakash.test;
public class MqttExampleOptions {
String projectId;
String registryId;
String deviceId;
String privateKeyFile;
String algorithm;
String cloudRegion;
int numMessages;
String mqttBridgeHostname;
short mqttBridgePort;
String messageType;
/** Construct an MqttExampleOptions class. */
public static MqttExampleOptions values() {
try {
MqttExampleOptions res = new MqttExampleOptions();
res.projectId = "_";
res.registryId = "_";
res.deviceId = "_";
res.privateKeyFile = "com/example/adityaprakash/test/rsa_private.pem";
res.algorithm = "RS256";
res.cloudRegion = "asia-east1";
res.numMessages = 100;
res.mqttBridgeHostname = "mqtt.googleapis.com";
res.mqttBridgePort = 8883;
res.messageType = "event";
return res;
} catch (Exception e) {
System.err.println(e.getMessage());
return null;
}
}
}
Please can anyone give a solution to this problem.
P.S. I know the code looks totally crappy.I don't have experience with Android programming,so please let it go.
The example you are following is not designed for Android.
res.privateKeyFile = "com/example/adityaprakash/test/rsa_private.pem";
Will not relate to the same directory on the Android file system.
I wrote up an AndroidThings explanation of how to talk to Cloud IoT Core here: http://blog.blundellapps.co.uk/tut-google-cloud-iot-core-mqtt-on-android/
You can setup communication like this (with your pem file going into the /raw directory)
// Setup the communication with your Google IoT Core details
communicator = new IotCoreCommunicator.Builder()
.withContext(this)
.withCloudRegion("your-region") // ex: europe-west1
.withProjectId("your-project-id") // ex: supercoolproject23236
.withRegistryId("your-registry-id") // ex: my-devices
.withDeviceId("a-device-id") // ex: my-test-raspberry-pi
.withPrivateKeyRawFileId(R.raw.rsa_private)
.build();
Source code is here: https://github.com/blundell/CloudIoTCoreMQTTExample
Note that the above is good enough for a secure environment or for testing that the end to end works. However if you wanted to release a production IoT device, you would look at embedding the PEM into the ROM and using private file storage access. https://developer.android.com/training/articles/keystore.html
An example of this can be found here: https://github.com/androidthings/sensorhub-cloud-iot
Specifically this class:
https://github.com/androidthings/sensorhub-cloud-iot/blob/e50bde0100fa81818ebbadb54561b3b68ccb64b8/app/src/main/java/com/example/androidthings/sensorhub/cloud/cloudiot/MqttAuthentication.java
You can then generate and use the PEM on the device:
public Certificate getCertificate() {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
certificate = ks.getCertificate("Cloud IoT Authentication");
if (certificate == null) {
Log.w(TAG, "No IoT Auth Certificate found, generating new cert");
generateAuthenticationKey();
certificate = ks.getCertificate(keyAlias);
}
Log.i(TAG, "loaded certificate: " + keyAlias);
}
and
private void generateAuthenticationKey() throws GeneralSecurityException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
kpg.initialize(new KeyGenParameterSpec.Builder("Cloud IoT Authentication",KeyProperties.PURPOSE_SIGN)
.setKeySize(2048)
.setCertificateSubject(new X500Principal("CN=unused"))
.setDigests(KeyProperties.DIGEST_SHA256)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.build());
kpg.generateKeyPair();
}
I'm pretty sure you're not doing the file I/O correctly. Your file, "com/example/adityaprakash/test/rsa_private.pem", doesn't correspond to an actual filepath on the device. The location of files on the device may be different than in your project. You will have to determine where on the device your file actually is.
On AndroidThings, it is easier to provide the authentication credentials in an Android Resource. See my fork of the WeatherStation sample to see how this works.
First, copy the private key file (e.g. rsa_private_pkcs8) to app/src/main/res/raw/privatekey.txt
Next, you can load the key used to calculate your JWT as:
Context mContext;
int resIdPk = getResources().getIdentifier("privatekey", "raw", getPackageName());
...
InputStream privateKey = mContext.getResources().openRawResource(resIdPk);
byte[] keyBytes = inputStreamToBytes(privateKey);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("EC");
One final note, it appears that you're referencing a file that is not in pkcs8 format, which will cause issues with Java. Make sure to use a key that is packaged in PKCS8 when opening credentials on Android (Java).
import com.independentsoft.exchange.Body;
import com.independentsoft.exchange.ItemInfoResponse;
import com.independentsoft.exchange.Mailbox;
import com.independentsoft.exchange.Message;
import com.independentsoft.exchange.Service;
import com.independentsoft.exchange.ServiceException;
public class Example {
public static void main(String[] args)
{
try
{
Service service = new Service("https://myserver/ews/Exchange.asmx", "user", "password");
Message message = new Message();
message.setSubject("Test");
message.setBody(new Body("Body text"));
message.getToRecipients().add(new Mailbox("John#mydomain.com"));
message.getCcRecipients().add(new Mailbox("Mark#mydomain.com"));
ItemInfoResponse response = service.send(message);
}
catch (ServiceException e)
{
System.out.println(e.getMessage());
System.out.println(e.getXmlMessage());
e.printStackTrace();
}
}
}
Hello! I tried to send an email, but did not work.
I'ved used a valid user and password, at message.getToRecipients I used my yahoo email address.
At output on eclipse this is my result. Where is my mistake ?
JWebServices for Exchange 2.0 evaluation version, www.independentsoft.com.
myserver
null
myserver
at com.independentsoft.exchange.Service.createItemImplementation(Unknown Source)
at com.independentsoft.exchange.Service.send(Unknown Source)
at com.independentsoft.exchange.Service.send(Unknown Source)
at com.independentsoft.exchange.Service.send(Unknown Source)
at com.independentsoft.exchange.Service.send(Unknown Source)
at Example.main(Example.java:26)
Caused by: java.net.UnknownHostException: myserver
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:901)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1293)
at java.net.InetAddress.getAllByName0(InetAddress.java:1246)
at java.net.InetAddress.getAllByName(InetAddress.java:1162)
at java.net.InetAddress.getAllByName(InetAddress.java:1098)
at org.apache.http.impl.conn.SystemDefaultDnsResolver.resolve(SystemDefaultDnsResolver.java:44)
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:101)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:318)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at com.independentsoft.exchange.Service.a(Unknown Source)
... 6 more
Replace "myserver" with real name of your Exchange server.
try to AutoDiscover your service url first:
Sample here
I'm trying to upload video in my youtube account with Simple Access API (API Key).
I'm getting this exception.
You chose src/resources/video.avi to upload.
Initiation Started
Initiation Completed
Exception: 401 Unauthorized
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:143)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:115)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:421)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:340)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:458)
at com.google.api.services.samples.YoutubeSample.queryGoogleYouTube(YoutubeSample.java:126)
at com.google.api.services.samples.YoutubeSample.main(YoutubeSample.java:152)
What is wrong?
Documentation to use Simple Access API (API Key) with youtube-API is very poor.
Could anyone help me?
My Simple Access API:
Simple API Access
Use API keys to identify your project when you do not need to access user data.
Key for server apps (with IP locking)
API key: AIzaSxxxxxxxxxxxxxxxxxxxxxxx-bVE8jRlzXY
IPs: Any IP allowed
Activated on: Feb 11, 2014 7:50 PM
Activated by: myaccount#gmail.com – you
This is my code.
package com.google.api.services.samples;
import com.google.api.client.googleapis.media.MediaHttpUploader;
import com.google.api.client.googleapis.media.MediaHttpUploaderProgressListener;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.InputStreamContent;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.YouTubeRequestInitializer;
import com.google.api.services.youtube.model.Video;
import com.google.api.services.youtube.model.VideoSnippet;
import com.google.api.services.youtube.model.VideoStatus;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class YoutubeSample {
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static YouTube youtube;
private static String VIDEO_FILE_FORMAT = "video/*";
private static final String APPLICATION_NAME = "YoutubeTest";
//Simple API Access
//Use API keys to identify your project when you do not need to access user data.
//Key for server apps (with IP locking)
private static final String API_KEY = "AIzaSxxxxxxxxxxxxxxxxxx-bVE8jRlzXY"; // This has changed.
private static File getVideoFromUser() throws IOException {
return new File("src/resources/video.avi");
}
private static void queryGoogleYouTube() throws Exception {
ClientCredentials.errorIfNotSpecified();
try {
//In this piece of code that is my difficulty
youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY,
new HttpRequestInitializer() {
public void initialize(HttpRequest request)
throws IOException {
}
})
.setApplicationName(APPLICATION_NAME)
.setYouTubeRequestInitializer(new YouTubeRequestInitializer(API_KEY)).build();
File videoFile = getVideoFromUser();
System.out.println("You chose " + videoFile + " to upload.");
Video videoObjectDefiningMetadata = new Video();
VideoStatus status = new VideoStatus();
status.setPrivacyStatus("public");
videoObjectDefiningMetadata.setStatus(status);
VideoSnippet snippet = new VideoSnippet();
Calendar cal = Calendar.getInstance();
snippet.setTitle("Test Upload via Java on " + cal.getTime());
snippet.setDescription("Video uploaded via YouTube Data API V3 using the Java library "
+ "on " + cal.getTime());
// Set your keywords.
List<String> tags = new ArrayList<String>();
tags.add("test");
tags.add("example");
tags.add("java");
tags.add("YouTube Data API V3");
tags.add("erase me");
snippet.setTags(tags);
videoObjectDefiningMetadata.setSnippet(snippet);
InputStreamContent mediaContent = new InputStreamContent(
VIDEO_FILE_FORMAT, new BufferedInputStream(
new FileInputStream(videoFile)));
mediaContent.setLength(videoFile.length());
YouTube.Videos.Insert videoInsert = youtube.videos().insert(
"snippet,statistics,status", videoObjectDefiningMetadata,
mediaContent);
MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(false);
MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
public void progressChanged(MediaHttpUploader uploader)
throws IOException {
switch (uploader.getUploadState()) {
case INITIATION_STARTED:
System.out.println("Initiation Started");
break;
case INITIATION_COMPLETE:
System.out.println("Initiation Completed");
break;
case MEDIA_IN_PROGRESS:
System.out.println("Upload in progress");
System.out.println("Upload percentage: "
+ uploader.getProgress());
break;
case MEDIA_COMPLETE:
System.out.println("Upload Completed!");
break;
case NOT_STARTED:
System.out.println("Upload Not Started!");
break;
}
}
};
uploader.setProgressListener(progressListener);
// Execute upload.
Video returnedVideo = videoInsert.execute();
// Print out returned results.
System.out
.println("\n================== Returned Video ==================\n");
System.out.println(" - Id: " + returnedVideo.getId());
System.out.println(" - Title: "
+ returnedVideo.getSnippet().getTitle());
System.out.println(" - Tags: "
+ returnedVideo.getSnippet().getTags());
System.out.println(" - Privacy Status: "
+ returnedVideo.getStatus().getPrivacyStatus());
System.out.println(" - Video Count: "
+ returnedVideo.getStatistics().getViewCount());
} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
e.printStackTrace();
} catch (Throwable t) {
System.err.println("Throwable: " + t.getMessage());
t.printStackTrace();
}
}
public static void main(String[] args) {
try {
queryGoogleYouTube();
} catch (Exception e) {
e.printStackTrace();
}
}
}
As you can see in the snippet you posted, the simple access API key is designed to identify your project (i.e. for the sake of quotas) when you do not need to access user data. Uploading a video into an account is a form of accessing user data, so you'll need to use oauth2, request the scope 'https://www.googleapis.com/auth/youtube.upload,' and then perform the upload with the access token.
Once you have that oauth2 flow running and your user grants access to the scope, it seems that the rest of your code looks right (but I'm not a Java expert so don't hold me to that!)
I am trying to connect to my gmail inbox to read messages through Java Application. I am using..
jdk1.6.0_13
javamail-1.4.3 libs - (mail.jar, mailapi.jar, imap.jar)
Below is my code : MailReader.java
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
public class MailReader
{
public static void main(String[] args)
{
readMail();
}
public static void readMail()
{
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
try
{
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", "myEmailId#gmail.com", "myPwd");
System.out.println("Store Connected..");
//inbox = (Folder) store.getFolder("Inbox");
//inbox.open(Folder.READ_WRITE);
//Further processing of inbox....
}
catch (MessagingException e)
{
e.printStackTrace();
}
}
}
I expect to get store connected, but call to store.connect() never returns and I get below output :
javax.mail.MessagingException: Connection timed out;
nested
exception is:
java.net.ConnectException: Connection timed out
at
com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:441)
at
javax.mail.Service.connect(Service.java:233)
at
javax.mail.Service.connect(Service.java:134)
at
ReadMail.readMail(ReadMail.java:21)
at ReadMail.main(ReadMail.java:10)
However I am able to SEND email by Java using SMTP, Transport.send() and same gmail account. But cannot read emails.
What can be the solution ?
IMAP work off a different port (143 for non-secure, 993 for secure) to sendmail (25) and I suspect that's blocked. Can you telnet on that port to that server e.g.
telnet imap.gmail.com {port number}
That'll indicate if you have network connectivity.
I have socket server in Java and now I need simple TCP socket in my iOS app that will:
Open socket connection
Be able to send and recieve messages
Close connection
So, only basic stuff... I need simplest solution possible.
I found few solutions, but none seem to work for me. If you could point me in right direction I will be very grateful. I need code with instructions.
Thanks!
package jcolibri.examples.ABXRecommender;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class FileServer {
public static void main (String [] args ) throws IOException {
// create socket
#SuppressWarnings("resource")
ServerSocket servsock = new ServerSocket(13267);
while (true) {
String str = "temp.png";
File myFile = new File(str);
String absolutePathOfFirstFile = myFile.getAbsolutePath();
FileInputStream fis = new FileInputStream(absolutePathOfFirstFile);
//File myFile = new File ("temp.png");
//FileInputStream fis = new FileInputStream(myFile);
System.out.println("Waiting...");
Socket sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
// sendfile
byte [] mybytearray = new byte [(int)myFile.length()];
#SuppressWarnings("resource")
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
sock.close();
}
}
}
This code is lightly adapted from somewhere. can't remember where though and it works for me. Your iOS code should know the IP address of your computer.
Hope that helps.