How to import google contacts in android (programatically)? - android

Can any body suggest a way, how to extract contacts from google to the android app?
Thanks!
Below is my code and I'm getting runtime error at line number 57. To be specific it shows exception in AsyncTask.
package com.example.isan.contacts;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import com.google.gdata.client.Query;
import com.google.gdata.client.Service;
import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.Link;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.NoLongerAvailableException;
import com.google.gdata.util.ServiceException;
public class MainActivity extends ActionBarActivity {
private URL feedUrl;
private static final String username="username";
private static final String pwd="password";
private ContactsService service;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url = "https://www.google.com/m8/feeds/contacts/username/full";
try {
this.feedUrl = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
new GetTask().execute();
}
private class GetTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
service = new ContactsService("Contacts");
try {
service.setUserCredentials(username, pwd);
} catch (AuthenticationException e) {
e.printStackTrace();
}
try {
queryEntries();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
private void queryEntries() throws IOException, ServiceException{
Query myQuery = new Query(feedUrl);
myQuery.setMaxResults(50);
myQuery.setStartIndex(1);
myQuery.setStringCustomParameter("showdeleted", "false");
myQuery.setStringCustomParameter("requirealldeleted", "false");
// myQuery.setStringCustomParameter("sortorder", "ascending");
// myQuery.setStringCustomParameter("orderby", "");
try{
ContactFeed resultFeed = (ContactFeed)this.service.query(myQuery, ContactFeed.class);
for (ContactEntry entry : resultFeed.getEntries()) {
printContact(entry);
}
System.err.println("Total: " + resultFeed.getEntries().size() + " entries found");
}
catch (NoLongerAvailableException ex) {
System.err.println("Not all placehorders of deleted entries are available");
}
}
private void printContact(ContactEntry contact) throws IOException, ServiceException{
System.err.println("Id: " + contact.getId());
if (contact.getTitle() != null)
System.err.println("Contact name: " + contact.getTitle().getPlainText());
else {
System.err.println("Contact has no name");
}
System.err.println("Last updated: " + contact.getUpdated().toUiString());
if (contact.hasDeleted()) {
System.err.println("Deleted:");
}
// ElementHelper.printContact(System.err, contact);
Link photoLink = contact.getLink("http://schemas.google.com/contacts/2008/rel#photo", "image/*");
if (photoLink.getEtag() != null) {
Service.GDataRequest request = service.createLinkQueryRequest(photoLink);
request.execute();
InputStream in = request.getResponseStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
RandomAccessFile file = new RandomAccessFile("/tmp/" + contact.getSelfLink().getHref().substring(contact.getSelfLink().getHref().lastIndexOf('/') + 1), "rw");
byte[] buffer = new byte[4096];
for (int read = 0; (read = in.read(buffer)) != -1; )
out.write(buffer, 0, read);
file.write(out.toByteArray());
file.close();
in.close();
request.end();
}
System.err.println("Photo link: " + photoLink.getHref());
String photoEtag = photoLink.getEtag();
System.err.println(" Photo ETag: " + (photoEtag != null ? photoEtag : "(No contact photo uploaded)"));
System.err.println("Self link: " + contact.getSelfLink().getHref());
System.err.println("Edit link: " + contact.getEditLink().getHref());
System.err.println("ETag: " + contact.getEtag());
System.err.println("-------------------------------------------\n");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

Its simple to do. You can try this code.
public static void printAllContacts(ContactsService myService)
throws ServiceException, IOException {
// Request the feed
URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/liz#gmail.com/full");
ContactFeed resultFeed = myService.getFeed(feedUrl, ContactFeed.class);
// Print the results
System.out.println(resultFeed.getTitle().getPlainText());
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
ContactEntry entry = resultFeed.getEntries().get(i);
System.out.println("\t" + entry.getTitle().getPlainText());
System.out.println("Email addresses:");
for (Email email : entry.getEmailAddresses()) {
System.out.print(" " + email.getAddress());
if (email.getRel() != null) {
System.out.print(" rel:" + email.getRel());
}
if (email.getLabel() != null) {
System.out.print(" label:" + email.getLabel());
}
if (email.getPrimary()) {
System.out.print(" (primary) ");
}
System.out.print("\n");
}
System.out.println("IM addresses:");
for (Im im : entry.getImAddresses()) {
System.out.print(" " + im.getAddress());
if (im.getLabel() != null) {
System.out.print(" label:" + im.getLabel());
}
if (im.getRel() != null) {
System.out.print(" rel:" + im.getRel());
}
if (im.getProtocol() != null) {
System.out.print(" protocol:" + im.getProtocol());
}
if (im.getPrimary()) {
System.out.print(" (primary) ");
}
System.out.print("\n");
}
System.out.println("Groups:");
for (GroupMembershipInfo group : entry.getGroupMembershipInfos()) {
String groupHref = group.getHref();
System.out.println(" Id: " + groupHref);
}
System.out.println("Extended Properties:");
for (ExtendedProperty property : entry.getExtendedProperties()) {
if (property.getValue() != null) {
System.out.println(" " + property.getName() + "(value) = " +
property.getValue());
} else if (property.getXmlBlob() != null) {
System.out.println(" " + property.getName() + "(xmlBlob)= " +
property.getXmlBlob().getBlob());
}
}
String photoLink = entry.getContactPhotoLink().getHref();
System.out.println("Photo Link: " + photoLink);
if (photoLink.getEtag() != null) {
System.out.println("Contact Photo's ETag: " + photoLink.getEtag());
}
System.out.println("Contact's ETag: " + entry.getEtag());
}
}
Please have a look at this, for complete guide on how to use the latest Contacts API version 3.
UPDATE
You will need to import these packages.
import com.google.gdata.client.*;
import com.google.gdata.client.contacts.*;
import com.google.gdata.data.*;
import com.google.gdata.data.contacts.*;
import com.google.gdata.data.extensions.*;
import com.google.gdata.util.*;
import java.io.IOException;
import java.net.URL;

There is no way to import your google contacts in your app
But you can access your current contacts in your app.

Related

ACRA 4.9.0 : How can I write ACRA report to file (in Application data folder)

I want to write the crash report in text file using latest Acra 4.9.0.
I can,t example for this latest version.
I tried using available documentation.
Acra is enabled
but it,s not writing in the file.
myApp
package com.myApp;
import org.acra.ACRA;
import android.app.AlertDialog;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.KeyEvent;
import android.view.View;
import com.myApp.Application.AppLauncher;
import com.myApp.interfaces.AppEvents;
import com.myApp.R;
import com.utils.Config;
import com.utils.Constants;
import com.utils.DeviceValidator;
public class myApp extends FragmentActivity
{
private AppLauncher appLauncher = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if(!ACRA.isACRASenderServiceProcess())
{
setContentView(R.layout.activity_myApp);
appLauncher = new AppLauncher();
appLauncher.registerEventListener(appEventsListener);
appLauncher.initApp(this);
}
}
#Override
public void onPause() {
super.onPause();
if(!DeviceValidator.isDeviceValid())
{
return;
}
appLauncher.activityOnPause();
}
#Override
protected void onRestart() {
super.onRestart();
}
#Override
protected void onStart()
{
super.onStart();
}
#Override
public void onResume()
{
super.onResume();
appLauncher.activityOnResume();
}
}
AcraApplication
package com.myAPP;
import org.acra.ACRA;
import org.acra.ReportField;
import org.acra.ReportingInteractionMode;
import org.acra.annotation.ReportsCrashes;
import org.acra.sender.HttpSender.Method;
import android.app.Application;
#ReportsCrashes(
formUri = "http://staging.jemtv.com/variable_dump/index.php",
customReportContent = { ReportField.REPORT_ID, ReportField.DEVICE_ID, ReportField.APP_VERSION_NAME, ReportField.ANDROID_VERSION, ReportField.STACK_TRACE, ReportField.CUSTOM_DATA, ReportField.LOGCAT },
httpMethod = Method.POST,
reportSenderFactoryClasses = org.acra.util.MyOwnSenderFactory.class,
mode = ReportingInteractionMode.SILENT
)
public class AcraApplication extends Application
{
public AcraApplication()
{
super();
}
#Override
public void onCreate() {
super.onCreate();
ACRA.init(this);
}
}
MyOwnSender
package org.acra.util;
import java.io.File;
import java.io.FileOutputStream;
import org.acra.ReportField;
import org.acra.collector.CrashReportData;
import org.acra.config.ACRAConfiguration;
import org.acra.sender.ReportSender;
import org.acra.sender.ReportSenderException;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;
public class MyOwnSender implements ReportSender {
private static final String FILE_NAME = "AcraReport.txt";
//private final Map<ReportField, String> mMapping = new HashMap<ReportField, String>();
//private FileWriter crashReport = null;
MyOwnSender(Context context, #NonNull ACRAConfiguration config)
{
Log.d("testAcra", "MyOwnSender created");
/* File logFile = new File(context.getFilesDir().getPath() + "/" + FILE_NAME, FILE_NAME);
try {
crashReport = new FileWriter(logFile, true);
} catch (IOException e) {
e.printStackTrace();
}*/
}
#Override
public void send(Context context, CrashReportData report) throws ReportSenderException
{
// Iterate over the CrashReportData instance and do whatever
// you need with each pair of ReportField key / String value
String finalReport = createCrashReport(report);
String tempFile = context.getFilesDir().getPath() + "/" + FILE_NAME;
try
{
File detailedFile = new File(tempFile);
if(!detailedFile.exists())
detailedFile.createNewFile();
FileOutputStream stream = new FileOutputStream(detailedFile, true);
stream.write(finalReport.getBytes());
Log.d("testAcra","adding to file: "+stream);
stream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
/*final Map<String, String> finalReport = remap(report);
try {
BufferedWriter buf = new BufferedWriter(crashReport);
Set<Entry<String, String>> set = reportBody.entrySet();
Iterator<Entry<String, String>> i = set.iterator();
while (i.hasNext()) {
Map.Entry<String, String> me = (Entry<String, String>) i.next();
buf.append("[" + me.getKey() + "]=" + me.getValue());
}
buf.flush();
buf.close();
} catch (IOException e) {
Log.e("TAG", "IO ERROR", e);
}*/
}
private String createCrashReport(CrashReportData crashReportData){
StringBuilder body = new StringBuilder();
body.append("ReportID : " + crashReportData.getProperty(ReportField.REPORT_ID))
.append("\n")
.append("DeviceID : " + crashReportData.getProperty(ReportField.DEVICE_ID))
.append("\n")
.append("AppVersionName : " + crashReportData.getProperty(ReportField.APP_VERSION_NAME))
.append("\n")
.append("Android Version : " + crashReportData.getProperty(ReportField.ANDROID_VERSION))
.append("\n")
.append("CustomData : " + crashReportData.getProperty(ReportField.CUSTOM_DATA))
.append("\n")
.append("STACK TRACE : \n" + crashReportData.getProperty(ReportField.STACK_TRACE))
.append("\n")
.append("LogCAT : \n" + crashReportData.getProperty(ReportField.LOGCAT));
return body.toString();
}
/* private Map<String, String> remap(Map<ReportField, String> report) {
Set<ReportField>fields = ACRA.getConfig().getReportFields();
final Map<String, String> finalReport = new HashMap<String, String>(report.size());
for (ReportField field : fields)
{
if (mMapping == null || mMapping.get(field) == null)
finalReport.put(field.toString(), report.get(field));
else
finalReport.put(mMapping.get(field), report.get(field));
}
return finalReport;
}*/
}
MyOwnSenderFactory
package org.acra.util;
import org.acra.config.ACRAConfiguration;
import org.acra.sender.ReportSender;
import org.acra.sender.ReportSenderFactory;
import android.content.Context;
import android.support.annotation.NonNull;
public class MyOwnSenderFactory implements ReportSenderFactory {
// NB requires a no arg constructor.
/*MyOwnSenderFactory()
{
Log.e("testAcra", "MyOwnSenderFactory created");
}*/
#Override
#NonNull
public ReportSender create(#NonNull Context context, #NonNull ACRAConfiguration config) {
// TODO Auto-generated method stub
return new MyOwnSender(context, config);
}
}
Because i was using jar file instead of aar
in my manifest i was missing
<service
android:name="org.acra.sender.SenderService"
android:exported="false"
android:process=":acra" />
enter code here
That,s why SendeService used in Acra was not starting.
I want to write in application data folder
That is called internal data
I have created my own saver class to handle all of those savings:
import android.content.Context;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
public class Saver {
static FileOutputStream fos;
static FileInputStream fis;
public static void save(String filename, String data, Context c){
try {
fos = c.openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String file;
public String getFile(){return file;}
public void setFile(String loc){
file = loc;
}
String result;
private static String mainLoad(String fn, Context c){
String collected = null;
try{
fis = c.openFileInput(fn);
byte[] dataArray = new byte[fis.available()];
while(fis.read(dataArray) != -1){
collected = new String(dataArray);
}
}catch(Exception e){
e.printStackTrace();
return null;
}finally{
try {
fis.close();
return collected;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
public static int loadInt(String fn, Context c){
if(mainLoad(fn,c) == null) return 0;
else return Integer.parseInt(mainLoad(fn,c));
}
public static double loadDouble(String fn, Context c){
if(mainLoad(fn,c) == null) return 0;
else return Double.parseDouble(mainLoad(fn,c));
}
public static float loadFloat(String fn, Context c){
return Float.parseFloat(mainLoad(fn,c));
}
public static String loadString(String fn, Context c){
return mainLoad(fn, c);
}
public static Boolean loadBoolean(String fn, Context c){
if(mainLoad(fn,c) == null) return false;
else return Boolean.parseBoolean(mainLoad(fn,c));
}
public static BigInteger loadBigInteger(String fn, Context c){
return new BigInteger(mainLoad(fn,c));
}
public static BigDecimal loadBigDecimal(String fn, Context c){
return new BigDecimal(mainLoad(fn,c));
}
}
I want to write the crash report in text file using latest Acra 4.9.0. I can,t example for this latest version.
If you want to write to a .txt file on server, try this backend. Uses the default sender:
<?php
// Outputs all POST parameters to a text file. The file name is the date_time of the report reception
$fileName = date('Y-m-d_H-i-s').'.txt';
$file = fopen($fileName,'w') or die('Could not create report file: ' . $fileName);
foreach($_POST as $key => $value) {
$reportLine = $key." = ".$value."\n";
fwrite($file, $reportLine) or die ('Could not write to report file ' . $reportLine);
}
fclose($file);
?>
If you only want to write locally, then the point of ACRA disappears as you cannot get the files.
If you create .txt files to transmit them, it is actually better to use the backend I linked. It transmits the raw data, and you can get all your fields in a .txt file

How can I extract the notification text in the Status Bar in lollipop version?

Dear all I was using the code attached below to extract the notifications text. but it didn't work in the lollipop version of android (v 5). Can you help me to fix the issue
import java.lang.reflect.Field;
import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
import de.ecspride.reactor.poc.model.Message;
import de.ecspride.reactor.poc.model.MessageParser;
#SuppressLint("NewApi")
public class DefaultBigView implements MessageParser {
private static final String TAG = DefaultBigView.class.getName();
private static final int ID_FIRST_LINE = 16909023; // bigContentView
#Override
public Message parse(Notification notification) {
// use simple method if bigContentView is not supported
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
return new DefaultView().parse(notification);
Message result = new Message();
try {
RemoteViews views = notification.bigContentView;
Class<?> rvClass = views.getClass();
Field field = rvClass.getDeclaredField("mActions");
field.setAccessible(true);
#SuppressWarnings("unchecked")
ArrayList<Parcelable> actions = (ArrayList<Parcelable>) field
.get(views);
for (Parcelable action : actions) {
try {
// create parcel from action
Parcel parcel = Parcel.obtain();
action.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
// check if is 2 / ReflectionAction
int tag = parcel.readInt();
if (tag != 2)
continue;
int viewId = parcel.readInt();
String methodName = parcel.readString();
if (methodName == null || !methodName.equals("setText")) {
Log.w(TAG, "#Big Not setText: " + methodName);
continue;
}
// should be 10 / Character Sequence, here
parcel.readInt();
// Store the actual string
String value = TextUtils.CHAR_SEQUENCE_CREATOR
.createFromParcel(parcel).toString();
Log.d(TAG, "Big viewId is " + viewId);
Log.d(TAG, "Big Found value: " + value);
// if (viewId == ID_FIRST_LINE) {
int indexDelimiter = value.indexOf(':');
if (indexDelimiter != -1) {
result.sender = value.substring(0, indexDelimiter);
result.message = value
.substring(indexDelimiter + 2);
}
// }
parcel.recycle();
} catch (Exception e) {
Log.e(TAG, "Big Error accessing object!", e);
}
}
if (result.sender == null || result.message == null)
return null;
return result;
} catch (Exception e) {
Log.e(TAG, "Big Could not access mActions!", e);
return null;
}
}
}
it gives me error that there are no declared variable mActions.
Thanks
Android 5 Lollipop notifications are not using RemoteViews class directly anymore, they are now using BuilderRemoteViews which extends the RemoteViews class.
You should just try to access the parent class mActions field like this
Field field = rvClass.getSuperclass().getDeclaredField("mActions");

How to connect android app to node server?

I am trying out the WebSockets with Fallbacks transports for Android, Node.js and Atmosphere example. I get an the following error:
/home/mofa/NetBeansProjects/App/src/com/jullio/advisor/wAsyncChat.java:87: error: cannot access JsonParseException
return mapper.readValue(data, Message.class);
class file for org.codehaus.jackson.JsonParseException not found
/home/mofa/NetBeansProjects/App/src/com/jullio/advisor/wAsyncChat.java:68: error: cannot access ObjectCodec
return mapper.writeValueAsString(data);
class file for org.codehaus.jackson.ObjectCodec not found
Here is the androidchat code:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.atmosphere.wasync.ClientFactory;
import org.atmosphere.wasync.Decoder;
import org.atmosphere.wasync.Encoder;
import org.atmosphere.wasync.Event;
import org.atmosphere.wasync.Function;
import org.atmosphere.wasync.Request;
import org.atmosphere.wasync.RequestBuilder;
import org.atmosphere.wasync.impl.AtmosphereClient;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
import java.util.Date;
public class wAsyncChat extends Activity {
private Button bt;
private TextView tv;
private String serverIpAddress = "http://10.0.2.2:8080";
private final static ObjectMapper mapper = new ObjectMapper();
private final Handler uiHandler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
setContentView(R.layout.main);
bt = (Button) findViewById(R.id.myButton);
tv = (TextView) findViewById(R.id.myTextView);
try {
AtmosphereClient client = ClientFactory.getDefault().newClient(AtmosphereClient.class);
RequestBuilder request = client.newRequestBuilder()
.method(Request.METHOD.GET)
.uri(serverIpAddress + "/chat")
.trackMessageLength(true)
.encoder(new Encoder<Message, String>() {
#Override
public String encode(Message data) {
try {
return mapper.writeValueAsString(data);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
})
.decoder(new Decoder<String, Message>() {
#Override
public Message decode(Event type, String data) {
data = data.trim();
// Padding
if (data.length() == 0) {
return null;
}
if (type.equals(Event.MESSAGE)) {
try {
return mapper.readValue(data, Message.class);
} catch (IOException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
}
})
.transport(Request.TRANSPORT.WEBSOCKET);
final org.atmosphere.wasync.Socket socket = client.create();
socket.on("message", new Function<Message>() {
#Override
public void on(final Message t) {
uiHandler.post(new Runnable() {
#Override
public void run() {
Date d = new Date(t.getTime());
tv.append("Author " + t.getAuthor() + "# " + d.getHours() + ":" + d.getMinutes() + ": " + t.getMessage() + "\n");
}
});
}
}).on(new Function<Throwable>() {
#Override
public void on(Throwable t) {
tv.setText("ERROR 3: " + t.getMessage());
t.printStackTrace();
}
}).open(request.build());
bt.setOnClickListener(new OnClickListener() {
String name = null;
public void onClick(View v) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
if (name == null) {
name = str;
}
socket.fire(new Message(name, str));
et.setText("");
Log.d("Client", "Client sent message");
} catch (Throwable e) {
tv.setText("ERROR 3: " + e.getMessage());
e.printStackTrace();
}
}
});
} catch (Throwable e) {
tv.setText("Unable to connect: " + e.getMessage());
e.printStackTrace();
}
}
}
I have the library for nodeserver connection. You can use it from git
SocketIO socketio = new SocketIO() {
#Override
public void onConnect() {
}
#Override
public void onDisconnect() {
}
#Override
public void onMessage(String message) {
Log.d("===Server Answer====",message);
}
};
socketio.Connect("192.168.0.1", 9000);
after onConnect() send the message:
socketio.send("Your message to socket");
it work with latest socketIO, and use RFC 6455 websocket protocol

Using NanoHTTPD in Android

I am trying to use NanoHTTP to serve up an HTML file. However, NanoHTTP is relatively un-documented, and I am new to Android. My question is, where do I store the html file, and how specifically can I serve it up using NanoHTTP.
A late answer but may be useful to others.
Here is a simple hello Web Server, not exactly what you ask, but you can continue from here. The following program supposes you have a www directory in the root of the SD Card and a file index.html inside.
Main activity Httpd.java:
package com.inforscience.web;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import java.io.*;
import java.util.*;
public class Httpd extends Activity
{
private WebServer server;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
server = new WebServer();
try {
server.start();
} catch(IOException ioe) {
Log.w("Httpd", "The server could not start.");
}
Log.w("Httpd", "Web server initialized.");
}
// DON'T FORGET to stop the server
#Override
public void onDestroy()
{
super.onDestroy();
if (server != null)
server.stop();
}
private class WebServer extends NanoHTTPD {
public WebServer()
{
super(8080);
}
#Override
public Response serve(String uri, Method method,
Map<String, String> header,
Map<String, String> parameters,
Map<String, String> files) {
String answer = "";
try {
// Open file from SD Card
File root = Environment.getExternalStorageDirectory();
FileReader index = new FileReader(root.getAbsolutePath() +
"/www/index.html");
BufferedReader reader = new BufferedReader(index);
String line = "";
while ((line = reader.readLine()) != null) {
answer += line;
}
reader.close();
} catch(IOException ioe) {
Log.w("Httpd", ioe.toString());
}
return new NanoHTTPD.Response(answer);
}
}
}
Obviously the NanoHTTPD class must be in the same package.
You need to grant internet permission in AndroidManifest.xml.
<uses-permission android:name="android.permission.INTERNET" />
and read external storage permission.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
EDIT: To access the server open you web browser with the IP of your device, e.g. 192.168.1.20:8080.
NOTES:
Tested in Android 2.3
The use of port 80 is restricted to the root user(http://www.mail-archive.com/android-developers#googlegroups.com/msg47377.html).
Pretty good source code can be found here:
https://github.com/Teaonly/android-eye
Chceck assets folder where html and JavaScript files are stored
https://github.com/Teaonly/android-eye/tree/master/assets
TeaServer - server implementation
https://github.com/Teaonly/android-eye/blob/master/src/teaonly/droideye/TeaServer.java
MainActivity - server initialization
https://github.com/Teaonly/android-eye/blob/master/src/teaonly/droideye/MainActivity.java
Updated WebServer class (see rendon's reply) that works with current NanoHTTPD version:
private class WebServer extends NanoHTTPD {
public WebServer() {
super(8080);
}
#Override
public Response serve(IHTTPSession session) {
String answer = "";
try {
// Open file from SD Card
File root = Environment.getExternalStorageDirectory();
FileReader index = new FileReader(root.getAbsolutePath() +
"/www/index.html");
BufferedReader reader = new BufferedReader(index);
String line = "";
while ((line = reader.readLine()) != null) {
answer += line;
}
reader.close();
} catch(IOException ioe) {
Log.w("Httpd", ioe.toString());
}
return newFixedLengthResponse(answer);
}
}
Take a look at how I serve HTML files and other type of files too.
I have a AndroidWebServer class which extends the Nanohttpd class.
This is my response method -->
public Response serve(IHTTPSession session) {
String uri=session.getUri();
String msg = "<html><body><h1>Hello server</h1>\n";
File [] arrayfile;
int i=0;
try{
session.parseBody(new HashMap<String, String>());
}catch (ResponseException | IOException r){
r.printStackTrace();
}
Map<String, String> parms = session.getParms();
if (parms.get("username") == null) {
msg += "<form action='?' method='get'>\n <p>Your name: <input type='text' name='username'></p>\n" + "</form>\n";
} else {
msg += "<p>Hello, " + parms.get("username") + "!</p>";
}
msg += "<br><br><a href='/Open_rap'>Open Image of Lionel Messi</a><br><br>";
msg += "<br><br><a href='/files'>Browse Files</a><br><br>";
msg += "<br><br><a href='/getmethod'>GET METHOD OPERATION</a><br><br>";
msg += "<br><br><a href='/postmethod'>POST METHOD OPERATION</a><br><br>";
msg += "<br><br><a href='/jquery'>JQUERY OPERATION</a><br><br>";
if(uri.equals("/hello")){
String response="Hello World";
return newFixedLengthResponse(response);
}
else if(uri.equals("/getmethod")){
String html="<html><head><h1>Welcome to the Form</h1><head/><body>";
if(parms.get("name")==null){
html +="<form action='' method='get'> \n " +
"<p>Enter Your Name:</p> <input type='text' name='name'>" +
"</form>" +
"</body>";
}
else{
html +="<p>Hello Mr. "+ parms.get("name") +"</p>"+
"</body> ";
}
html +="</html>";
return newFixedLengthResponse(html);
}
else if(uri.equals("/postmethod")){
String html="<html><head><h1>Welcome to the Form</h1><head/><body>";
Map<String, String> files = new HashMap<String, String>();
Method method = session.getMethod();
String postParameter="";
html +="<form action='' method='post'> \n " +
"<p>Enter Your Name:</p> <input type='text' name='name'>" +
"</form>";
if (Method.POST.equals(method) || Method.PUT.equals(method)) {
try {
session.parseBody(files);
} catch (IOException ioe) {
try {
// return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
} catch (Exception e) {
e.printStackTrace();
Log.d("Exception", e.getMessage());
}
} catch (ResponseException re) {
try {
// return newFixedLengthResponse(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
} catch (Exception e) {
e.printStackTrace();
Log.d("Exception", re.getMessage());
}
}
}
html +="</body></html>";
String postBody = session.getQueryParameterString();
postParameter = session.getParms().get("name");
Log.d("Postbody",postBody+"\n"+postParameter);
if(postParameter!=null){
String html1="<html><head><h1>"+ postParameter +"</h1><head></html>";
return newFixedLengthResponse(html1);
}
return newFixedLengthResponse(Response.Status.OK,"text/html",html);
}
else if(uri.equals("/Open_rap")){
File root= Environment.getExternalStorageDirectory();
FileInputStream fis = null;
File file = new File(root.getAbsolutePath() + "/www/messi.jpg");
Log.d("Path",root.getAbsolutePath());
try{
if(file.exists())
{
fis = new FileInputStream(file);
}
else
Log.d("FOF :", "File Not exists:");
}catch (FileNotFoundException e)
{
e.printStackTrace();
}
return newFixedLengthResponse(Response.Status.OK,"image/jpeg",fis, file.length() );
}
else {
return newFixedLengthResponse(msg + "</body></html>\n");
}
}
As you can see, I have implemented GET and POST method. You can find each in this part of the code uri.equals("/getmethod") and uri.equals("/getmethod").
Also, you can see the part --> uri.equals("/openrap") , here I am serving a JPG file to the client's browser and the image is present in the internal directory at /www/ folder.
Ping me if you have any doubts.
Try this...
Create 2 packages(activity, util), only for organization
In activity create the class MainActivity.java in util create the class AndroidWebServer.java
package awserverfatepi.com.activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import awserverfatepi.com.R;
import awserverfatepi.com.util.AndroidWebServer;
public class MainActivity extends AppCompatActivity {
private static final int DEFAULT_PORT = 8080;
private AndroidWebServer androidWebServer;
private BroadcastReceiver broadcastReceiverNetworkState;
private static boolean isStarted = false;
private CoordinatorLayout coordinatorLayout;
private EditText editTextPort;
private FloatingActionButton floatingActionButtonOnOff;
private View textViewMessage;
private TextView textViewIpAccess;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initGui();
setIpAccess();
floatingActionButtonOnOff = (FloatingActionButton) findViewById(R.id.floatingActionButtonOnOff);
floatingActionButtonOnOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isConnectedInWifi()) {
if (!isStarted && startAndroidWebServer()) {
isStarted = true;
textViewMessage.setVisibility(View.VISIBLE);
floatingActionButtonOnOff.setBackgroundTintList(ContextCompat.getColorStateList(MainActivity.this,
R.color.colorGreen));
editTextPort.setEnabled(false);
} else if (stopAndroidWebServer()) {
isStarted = false;
textViewMessage.setVisibility(View.INVISIBLE);
floatingActionButtonOnOff.setBackgroundTintList(ContextCompat.getColorStateList(MainActivity.this,
R.color.colorRed));
editTextPort.setEnabled(true);
}
} else {
Snackbar.make(coordinatorLayout, getString(R.string.wifi_message), Snackbar.LENGTH_LONG).show();
}
}
});
initBroadcastReceiverNetworkStateChanged();
}
private void initGui() {
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
editTextPort = (EditText) findViewById(R.id.editTextPort);
textViewMessage = findViewById(R.id.textViewMessage);
textViewIpAccess = (TextView) findViewById(R.id.textViewIpAccess);
}
private boolean startAndroidWebServer() {
if (!isStarted) {
int port = getPortFromEditText();
try {
if (port == 0) {
throw new Exception();
}
androidWebServer = new AndroidWebServer(port);
androidWebServer.start();
return true;
} catch (Exception e) {
e.printStackTrace();
Snackbar.make(coordinatorLayout, "A porta " + port + " não está funcionando, por favor altere para outra no intervalo" +
" entre 1000 e 9999.", Snackbar.LENGTH_LONG).show();
}
}
return false;
}
private boolean stopAndroidWebServer() {
if (isStarted && androidWebServer != null) {
androidWebServer.stop();
return true;
}
return false;
}
private void setIpAccess() {
textViewIpAccess.setText(getIpAccess());
}
private void initBroadcastReceiverNetworkStateChanged() {
final IntentFilter filters = new IntentFilter();
filters.addAction("android.net.wifi.WIFI_STATE_CHANGED");
filters.addAction("android.net.wifi.STATE_CHANGE");
broadcastReceiverNetworkState = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
setIpAccess();
}
};
super.registerReceiver(broadcastReceiverNetworkState, filters);
}
private String getIpAccess() {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
final String formatedIpAddress = String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff),
(ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff));
return "http://" + formatedIpAddress + ":";
}
private int getPortFromEditText() {
String valueEditText = editTextPort.getText().toString();
return (valueEditText.length() > 0) ? Integer.parseInt(valueEditText) : DEFAULT_PORT;
}
public boolean isConnectedInWifi() {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
NetworkInfo networkInfo = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected()
&& wifiManager.isWifiEnabled() && networkInfo.getTypeName().equals("WIFI")) {
return true;
}
return false;
}
public boolean onKeyDown(int keyCode, KeyEvent evt) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (isStarted) {
new AlertDialog.Builder(this)
.setTitle(R.string.warning)
.setMessage(R.string.dialog_exit_message)
.setPositiveButton(getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
})
.setNegativeButton(getResources().getString(android.R.string.cancel), null)
.show();
} else {
finish();
}
return true;
}
return false;
}
#Override
protected void onDestroy() {
super.onDestroy();
stopAndroidWebServer();
isStarted = false;
if (broadcastReceiverNetworkState != null) {
unregisterReceiver(broadcastReceiverNetworkState);
}
}
}
In the AndroidWebserver.java
package awserverfatepi.com.util;
import java.util.Map;
import fi.iki.elonen.NanoHTTPD;
public class AndroidWebServer extends NanoHTTPD {
public AndroidWebServer(int port) {
super(port);
}
public AndroidWebServer(String hostname, int port) {
super(hostname, port);
}
#Override
public Response serve(IHTTPSession session) {
String msg = "<html><body><h1>Hello World</h1>\n";
Map<String, String> parms = session.getParms();
if (parms.get("username") == null) {
msg += "<form action='?' method='get'>\n <p>Seu nome: <input type='text' name='username'></p>\n" + "</form>\n";
} else {
msg += "<p>Hello, " + parms.get("username") + "!</p>";
}
return newFixedLengthResponse( msg + "</body></html>\n" );
}
}
Don't forget Manifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And last
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="#drawable/header" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/colorPrimaryLight"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/textViewIpAccess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="http://000.000.000.000:"
android:textColor="#android:color/white"
android:textSize="20sp"
android:textStyle="bold" />
<EditText
android:id="#+id/editTextPort"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:gravity="center"
android:hint="8080"
android:inputType="numberDecimal"
android:maxLength="4"
android:text="8080"
android:textColor="#android:color/white"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
<TextView
android:id="#+id/textViewMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:layout_marginTop="50dp"
android:gravity="center"
android:text="#string/message"
android:textColor="#android:color/white"
android:textSize="18sp"
android:visibility="invisible" />
</LinearLayout>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/floatingActionButtonOnOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:elevation="4dp"
android:src="#drawable/on_btn"
app:backgroundTint="#color/colorRed" />
</android.support.design.widget.CoordinatorLayout>
One more example based on previous posts with AssetManager, MimeTypes and routing.
This static server will work for React apps. Your can run React app by using Andorid WebView. Create main/assets/index.html or copy React build folder into main/assets/ directory. Add url http://localhost:8080 to your WebView or browser.
package com.example.httpd;
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import java.io.*;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.Random;
import fi.iki.elonen.NanoHTTPD;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private HttpServer server;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
server = new HttpServer();
try {
server.start();
} catch (IOException ioe) {
Log.d(TAG, "The server could not start.");
}
Log.d(TAG, "Web server initialized.");
}
// DON'T FORGET to stop the server
#Override
public void onDestroy() {
super.onDestroy();
if (server != null)
server.stop();
}
private class HttpServer extends NanoHTTPD {
public static final String
MIME_PLAINTEXT = "text/plain",
MIME_HTML = "text/html",
MIME_JS = "application/javascript",
MIME_CSS = "text/css",
MIME_PNG = "image/png",
MIME_DEFAULT_BINARY = "application/octet-stream",
MIME_XML = "text/xml";
private static final int PORT = 8080;
private static final String TAG = "HttpServer";
private AssetManager assetManager;
public HttpServer() {
super(PORT);
}
#Override
public Response serve(IHTTPSession session) {
assetManager = getAssets();
InputStream inputStream;
Response response = newChunkedResponse(Response.Status.BAD_REQUEST, MIME_PLAINTEXT, null);
String uri = session.getUri();
try {
if (session.getMethod() == Method.GET && uri != null) {
if (uri.contains(".js")) {
inputStream = assetManager.open(uri.substring(1));
return newChunkedResponse(Response.Status.OK, MIME_JS, inputStream);
} else if (uri.contains(".css")) {
inputStream = assetManager.open(uri.substring(1));
return newChunkedResponse(Response.Status.OK, MIME_CSS, inputStream);
} else if (uri.contains(".png")) {
inputStream = assetManager.open(uri.substring(1));
return newChunkedResponse(Response.Status.OK, MIME_PNG, inputStream);
} else if (uri.contains("/mnt/sdcard")) {
Log.d(TAG, "request for media on sdCard " + uri);
File file = new File(uri);
FileInputStream fileInputStream = new FileInputStream(file);
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentType = fileNameMap.getContentTypeFor(uri);
Response streamResponse = newChunkedResponse(Response.Status.OK, contentType, fileInputStream);
Random random = new Random();
String hexString = Integer.toHexString(random.nextInt());
streamResponse.addHeader("ETag", hexString);
streamResponse.addHeader("Connection", "Keep-alive");
return streamResponse;
} else {
inputStream = assetManager.open("index.html");
return newChunkedResponse(Response.Status.OK, MIME_HTML, inputStream);
}
}
} catch (IOException e) {
Log.d(TAG, e.toString());
}
return response;
}
}
}
build.gradle
dependencies {
...
implementation 'org.nanohttpd:nanohttpd:2.3.1'
...
}
res/values/strings.html
<resources>
<string name="http_index">index.html</string>
</resources>
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Have a nice day! :)

How to get gmail user's contacts?

I need to retrieve the email addresses that the user has stored in his gmail account. In my app, the user can now decide to invite a friend of him. I want that the application (if the user tell me "ok") presents a list of the user's contacts email addresses stored in gmail, among which he can choose one or more...
I know that exists Authentication and Authorization for Google APIs". Is it the right way? And, how to use them in Android?
I hope this will help for someone like me, because I have searched a lot for this and finally done with the below.
I have used GData java client library for Google Contacts API v3.
package com.example.cand;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import com.google.gdata.client.Query;
import com.google.gdata.client.Service;
import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.Link;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.NoLongerAvailableException;
import com.google.gdata.util.ServiceException;
public class MainActivity extends Activity {
private URL feedUrl;
private static final String username="yourUsername";
private static final String pwd="yourPassword";
private ContactsService service;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url = "https://www.google.com/m8/feeds/contacts/default/full";
try {
this.feedUrl = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
new GetTask().execute();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class GetTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
service = new ContactsService("ContactsSample");
try {
service.setUserCredentials(username, pwd);
} catch (AuthenticationException e) {
e.printStackTrace();
}
try {
queryEntries();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
private void queryEntries() throws IOException, ServiceException{
Query myQuery = new Query(feedUrl);
myQuery.setMaxResults(50);
myQuery.setStartIndex(1);
myQuery.setStringCustomParameter("showdeleted", "false");
myQuery.setStringCustomParameter("requirealldeleted", "false");
// myQuery.setStringCustomParameter("sortorder", "ascending");
// myQuery.setStringCustomParameter("orderby", "");
try{
ContactFeed resultFeed = (ContactFeed)this.service.query(myQuery, ContactFeed.class);
for (ContactEntry entry : resultFeed.getEntries()) {
printContact(entry);
}
System.err.println("Total: " + resultFeed.getEntries().size() + " entries found");
}
catch (NoLongerAvailableException ex) {
System.err.println("Not all placehorders of deleted entries are available");
}
}
private void printContact(ContactEntry contact) throws IOException, ServiceException{
System.err.println("Id: " + contact.getId());
if (contact.getTitle() != null)
System.err.println("Contact name: " + contact.getTitle().getPlainText());
else {
System.err.println("Contact has no name");
}
System.err.println("Last updated: " + contact.getUpdated().toUiString());
if (contact.hasDeleted()) {
System.err.println("Deleted:");
}
// ElementHelper.printContact(System.err, contact);
Link photoLink = contact.getLink("http://schemas.google.com/contacts/2008/rel#photo", "image/*");
if (photoLink.getEtag() != null) {
Service.GDataRequest request = service.createLinkQueryRequest(photoLink);
request.execute();
InputStream in = request.getResponseStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
RandomAccessFile file = new RandomAccessFile("/tmp/" + contact.getSelfLink().getHref().substring(contact.getSelfLink().getHref().lastIndexOf('/') + 1), "rw");
byte[] buffer = new byte[4096];
for (int read = 0; (read = in.read(buffer)) != -1; )
out.write(buffer, 0, read);
file.write(out.toByteArray());
file.close();
in.close();
request.end();
}
System.err.println("Photo link: " + photoLink.getHref());
String photoEtag = photoLink.getEtag();
System.err.println(" Photo ETag: " + (photoEtag != null ? photoEtag : "(No contact photo uploaded)"));
System.err.println("Self link: " + contact.getSelfLink().getHref());
System.err.println("Edit link: " + contact.getEditLink().getHref());
System.err.println("ETag: " + contact.getEtag());
System.err.println("-------------------------------------------\n");
}
}
Required library files: you can get these jars from here
gdata-client-1.0.jar
gdata-client-meta-1.0.jar
gdata-contacts-3.0.jar
gdata-contacts-meta-3.0.jar
gdata-core-1.0.jar
guava-11.0.2.jar
Note: Add internet permission in AndroidManifest file.
<uses-permission android:name="android.permission.INTERNET"/>

Categories

Resources