How to get Mobile Device Identification in Webservice - android

I have android native application & web service. Our application is University application. Generate long live token for session issue.So we planned to go for MDM, i searched on Google, , I got some solution
Open Mobster (Open Source Mobile Enterprise Backend)
Apache USerGrid_ (Mobile Backend as a service)
OpenMeap - not support native
Problem is I could not find out , whether this MDM are provide device identification facility.If any one knows about it please tell me. Device identification may be any unique id or mac address
or If i am going to developed our own middle layer , how we can get mac address from request header. without passing to service method , from the request should take.
is there any way to take sort-out this issue?
Please help me

Here is how OpenMEAP grabs the Mac address and passes it in the header.
package com.openmeap.thinclient;
import java.io.ByteArrayInputStream;
import com.openmeap.http.HttpRequestExecuter;
import com.openmeap.http.HttpResponse;
import com.openmeap.util.Utils;
public class FirstRunCheck implements Runnable {
private SLICConfig config;
private String macAddress;
private HttpRequestExecuter executer;
public FirstRunCheck(SLICConfig config, String macAddress, HttpRequestExecuter executer) {
this.config = config;
this.macAddress = macAddress;
this.executer = executer;
}
public void run() {
if( config.isDevelopmentMode().equals(Boolean.TRUE) ) {
return;
}
if( config.getNotFirstRun()==null ) {
config.setNotFirstRun(Boolean.TRUE);
try {
String macWithSalt = macAddress+".OPENMEAP#$!#3__234";
String hashValue = Utils.hashInputStream("sha1", new ByteArrayInputStream(macWithSalt.getBytes("UTF-8")));
HttpResponse response = executer.get("http://usage.openmeap.com/tracker.gif?hash="+hashValue);
Utils.consumeInputStream(response.getResponseBody());
} catch( Exception ioe ) {
return;
}
}
}
}

Related

MySQL connection using jdbc, android studio

I'm new to Android Studio and I hope you don't consider my question silly.I am trying to write a small program in the terminal of the android studio.When I try to run the same program in my terminal(not android studio) it's working fine.I added the MySQL-connector.jar file in android studio lib by going through this mysql JDBC driver to the android studio.But it didn't work.Please help me.Thanks in advance.
//MySQConnectionExample.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class MySQLConnectionExample {
public static void main(String[] args) {
Connection conn1 = null;
String result = " ";
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://127.0.0.1:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
if (conn1 != null) {
System.out.println("Connected to the database test1");
}
String sql = " select address from pharmacy";
PreparedStatement prest = conn1.prepareStatement(sql);
ResultSet rs = prest.executeQuery();
while(rs.next()) {
result = rs.getString(1);
System.out.println(result);
}
} catch (SQLException ex) {
System.out.println("An error occurred. Maybe user/password is invalid");
ex.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//Error after execution
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at MySQLConnectionExample.main(MySQLConnectionExample.java:16)
When I remove "Class.forName("com.mysql.jdbc.Driver")" from the program this is the error i get
An error occurred. Maybe user/password is invalid
java.sql.SQLException: No suitable driver found for
jdbc:mysql://127.0.0.1:3306/demo
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at MySQLConnectionExample.main(MySQLConnectionExample.java:22)
You can't connect directly to databases from android devices. Build APIs that connects to your database. then connect your Android Application to these APIs.
Check this answer for a the same question https://stackoverflow.com/a/12233178/4442067
I assume you're trying to directly connect to a MySQL database from your Android device. But first, you have a ClassNotFound exception, which means you haven't imported the library.
And when you get the driver to work, there's more problem in this part:
....
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://127.0.0.1:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
....
By specifying 127.0.0.1 on your Android device, you're trying to connect to a MySQL server on your device. Now I don't know if you can install MySQL on Android, but you may want to install a MySQL server on your computer. This goes without saying that you must use the IP of that computer and have the MySQL port (3306) open on your computer.
So, what you may want to see is something like
....
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://192.168.1.10:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
....
This assumes your MySQL server is installed and configured on your computer with IP address 192.168.1.10
Good luck.
EDIT: I can't really recommend this approach for a production application though, because I'm afraid what a hacker who can decompile your code can do with it.

android : Get or create unique id for each device

I am developing an application using api 14 (android 4.0).
in manifest:
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="14" />
I want to get an unique id from each device (or create one) that could be the same even after reboot the device. But it is important that the id be different even for 2 same devices. How can i do that?
You can use device's IMEI number as unique Id.
You want to call android.telephony.TelephonyManager.getDeviceId().
This will return whatever string uniquely identifies the device (IMEI on GSM, MEID for CDMA).
You'll need the following permission in your AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
You can generate different device token using GCM....
And this device token will remain same even if you will uninstall and again installed the application or after factory setting.. you have to follow some steps......
Create a new project at Google Developers Console .
At this step, for simplicity, you just need to take note of 2 values: Project Number, which will be used as SENDER_ID in the client project; and API server key (created at Credentials), which will be used as API_KEY in the server project.
Create a new simple Android project for server side (with basic source code as my answer in the following links).
Create a new simple Android project for client side (with basic source code as my answer in the following links, I customized from the original source at Google Cloud Messaging - GitHub).
Run the client app, you will get the registration token (means that your device has successfully registered). Then, paste (hard-code) this token at CLIENT_REGISTRATION_TOKEN variable in server app (or write code to send this token to server app).
You can read more at the following questions, one of them you have read before with one of your previous questions:
How to implement a GCM Hello World for Android using Android Studio
Adding Google Cloud Messagin (GCM) for Android - Registration process
Try this one String android_id = Settings.Secure.getString(getApplicationContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
Here android_id is the unique Id for each device.
Try this code
String UniqueDeviceId = AndroidDeviceIdentifier.getUniqueDeviceIdentifier(context);
Add this class too.
final class AndroidDeviceIdentifier {
private AndroidDeviceIdentifier() {
// hidden constructor of singleton
}
/**
* Returns a stable identifier for the current device.
*
* #param ctx The application's Context
* #return The unique device identifier
* #throws IllegalStateException If the device's identifier could not be determined
*/
public static String getUniqueDeviceIdentifier(#NonNull final Context ctx) throws IllegalStateException {
try {
return getDeviceUUID(ctx);
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
throw new IllegalStateException("Could not determine device identifier", e);
}
}
private static String getDeviceUUID(Context ctx) throws UnsupportedEncodingException, NoSuchAlgorithmException {
byte[] hash = makeHash(getMac(ctx), getSerialNumber(ctx));
return createUUIDFromHash(hash);
}
private static String createUUIDFromHash(byte[] hash) {
return UUID.nameUUIDFromBytes(hash).toString().toLowerCase(); // Server side wants lower cased UUIDs
}
private static byte[] makeHash(final String mac, final String serialNumber) throws UnsupportedEncodingException, NoSuchAlgorithmException {
MessageDigest sha;
sha = MessageDigest.getInstance("SHA-256");
sha.reset();
sha.update(mac.getBytes("UTF-8"));
sha.update(serialNumber.getBytes("UTF-8"));
return sha.digest();
}
private static String getSerialNumber(Context context) {
String serialNumber = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
if (serialNumber == null) {
serialNumber = "0000000000000000";
}
return serialNumber;
}
private static String getMac(Context context) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String mac = wifiManager.getConnectionInfo().getMacAddress();
if (mac == null) {
mac = "000000000000";
}
return mac;
}
You will get a unique device id. Ping me if u have any questions
Try out this code below ,this device id is constant and even if you uninstall the app and reinstall this id remains constant and you can use it to retrieve the user data from database as well.
final String android_id = Settings.Secure.getString(getApplicationContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
Just paste this code in your main activity or any function and can store the ID generated in the shared Preference for later use.

How to properly install mysql connector in Eclipse?

First of all I'd like to say that it is a project for a course in my university and at the same time my first app for Android which is more complicated that a calculator, so I understand that I could have done some unforgivable mistakes, but my priority is that the code should work. It can be insecure and not considering some cases, but as long as those cases won't appear, it will do.
My app is intended to be running on Android and first of all there should appear login screen which takes login and password, makes the hash of the password and contacts a database on a web server to compare hashes. I was told to use a free database db4free.net.
I created a class Serwer, which would be responsible exclusively for contacting the database. As far as I understood from tutorials and stackoverflow questions and answers, the connection should consist of:
Loading the driver,
Registering it in the DriverManager class,
Using getConnection method to open the connection, passing the credentials,
Preparing and executing SQL query,
Fetching a result set.
I also learned that I should download a mysql-connector-java-5.1.38-bin.jar file. As some threads on stackoverflow suggested, I copied it into main directory of the project (I have to copy the workspace and take to professor's computer when I finish), added it to Libraries tab of properties as an external library. Now when I run the project on my smartphone, I get a java.lang.ClassNotFoundException: Didn't find class "com.mysql.jdbc.Driver" error. I also tried to check the library in Order and Export tab - then it even doesn't compile, returning Conversion to Dalvik format failed with error 1.
I've tried many scenarios in other stackoverflow threads, such as cleaning the project in many configurations, changing the order of build path, etc. I suspect that I've made a simple, stupid mistake that I do not see and I hope you will recognize it.
Here is my Serwer class:
package com.planer.serwer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Driver;
import com.planer.MainActivity;
import com.example.planer.R;
import com.planer.pracownik.Pracownik;
public class Serwer {
private Connection conn = null;
private static Driver driver;
private static int status;
private MainActivity parentActivity;
private final String user = parentActivity.getResources().getString(R.string.db_login);
private final String pass = parentActivity.getResources().getString(R.string.db_pass);
private final String url= "jdbc:mysql://db4free.net:3306/kalendarzplaner";
public static final int STATUS_GOOD = 0;
public static final int STATUS_NO_CONNECTION = 1;
public static final int STATUS_NOT_AUTHENTICATED = 2;
public static final int STATUS_SQL_EXCEPTION = 4;
public static final int STATUS_NO_DRIVER = 8;
public Serwer(MainActivity parentActivity){
status = STATUS_NO_CONNECTION;
try {
driver = new com.mysql.jdbc.Driver();
} catch (Exception ex) {
status |= STATUS_NO_DRIVER;
} catch (NoClassDefFoundError e){
status |= STATUS_NO_DRIVER;
}
this.parentActivity = parentActivity;
}
public Pracownik authorize(String login, String passhash){
Pracownik pracownik = new Pracownik("","",false,status);
status |= this.polacz();
if(status != Serwer.STATUS_GOOD) {
pracownik.status |= status;
return pracownik;
}
Statement statement = null;
ResultSet resultSet = null;
String query = "select passhash, imie_nazwisko, czy_kierownik from auth where login='" + login + "';";
try {
statement = conn.prepareStatement(query);
resultSet = statement.executeQuery(query);
resultSet.first();
if(resultSet.getString("passhash").toString().compareTo(passhash)!= 0){
status |= Serwer.STATUS_NOT_AUTHENTICATED;
pracownik.status |= status;
return pracownik;
}
pracownik.login = login;
pracownik.imie_nazwisko = resultSet.getString("imie_nazwisko");
pracownik.czy_kierownik = resultSet.getBoolean("czy_kierownik");
} catch (SQLException ex) {
pracownik.status |= Pracownik.STATUS_SQL_EXCEPTION;
}
return pracownik;
}
public int polacz() {
int done = STATUS_NO_CONNECTION;
if((status & STATUS_NO_DRIVER) != 0)
return done;
// Connection
try {
DriverManager.registerDriver(driver);
conn = DriverManager.getConnection(url, user, pass);
done = Serwer.STATUS_GOOD;
} catch (java.sql.SQLException ex) {
done |= Serwer.STATUS_SQL_EXCEPTION;
System.out.println("SQLException: " + ex.getMessage());
}
return done;
}
}
As I said, the status of the result of authorise method is 9, which is expected when the driver is not loaded. I also append my workspace contents.
First, I want to start by suggesting that you tried out Android Studio. It's the new more modern IDE developed specifically for the purpose of Android Development.
Secondly, contacting a database on Android is a lot different than for example contacting a DB from Java/C# in an Desktop application.
To contact an online MySQL Database you need a RESTful service (written in PHP for example) that gets the data from the database and sends it over to the application. The service is like a communication point between the App and the Database. The service usually sends data to the application in a human-unfriendly format like JSON, so your app needs to parse that and then display it.

GCM Service for android shows java.net.UnknownHostException: android.googleapis.com

Code for the GCMService:
package com.avilyne.gcm;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Sender;
/**
* Servlet implementation class GCMBroadcast
*/
#WebServlet("/GCMBroadcast")
public class GCMBroadcast extends HttpServlet {
private static final long serialVersionUID = 1L;
// The SENDER_ID here is the "Browser Key" that was generated when I
// created the API keys for my Google APIs project.
private static final String SENDER_ID = "AIzaSyCOLAYwS2P3ELqnTiPs3VPHGquQy1UoEIQ";
// This is a *cheat* It is a hard-coded registration ID from an Android device
// that registered itself with GCM using the same project id shown above.
private static final String ANDROID_DEVICE = "APA91bEF-_Y7t3Vc59OGuK9gnBWDegE4g2KyVgNeVIZbjGWe-4b9FMHrL82oOEYRPVz7_GaCOHbq3PatsuU_pk8jhvGng3Xp-CAv48iPqamer8Y2aajyTvUho9hsy39uNudA8XI4ML09eUsPNH87zcuGc_v2uJj65g";
// This array will hold all the registration ids used to broadcast a message.
// for this demo, it will only have the ANDROID_DEVICE id that was captured
// when we ran the Android client app through Eclipse.
private List<String> androidTargets = new ArrayList<String>();
/**
* #see HttpServlet#HttpServlet()
*/
public GCMBroadcast() {
super();
// we'll only add the hard-coded *cheat* target device registration id
// for this demo.
androidTargets.add(ANDROID_DEVICE);
}
// This doPost() method is called from the form in our index.jsp file.
// It will broadcast the passed "Message" value.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// We'll collect the "CollapseKey" and "Message" values from our JSP page
String collapseKey = "";
String userMessage = "";
try {
userMessage = request.getParameter("Message");
collapseKey = request.getParameter("CollapseKey");
} catch (Exception e) {
e.printStackTrace();
return;
}
// Instance of com.android.gcm.server.Sender, that does the
// transmission of a Message to the Google Cloud Messaging service.
Sender sender = new Sender(SENDER_ID);
// This Message object will hold the data that is being transmitted
// to the Android client devices. For this demo, it is a simple text
// string, but could certainly be a JSON object.
Message message = new Message.Builder()
// If multiple messages are sent using the same .collapseKey()
// the android target device, if it was offline during earlier message
// transmissions, will only receive the latest message for that key when
// it goes back on-line.
.collapseKey(collapseKey)
.timeToLive(30)
.delayWhileIdle(true)
.addData("message", userMessage)
.build();
try {
// use this for multicast messages. The second parameter
// of sender.send() will need to be an array of register ids.
MulticastResult result = sender.send(message, androidTargets, 1);
if (result.getResults() != null) {
int canonicalRegId = result.getCanonicalIds();
if (canonicalRegId != 0) {
}
} else {
int error = result.getFailure();
System.out.println("Broadcast failure: " + error);
}
} catch (Exception e) {
e.printStackTrace();
}
// We'll pass the CollapseKey and Message values back to index.jsp, only so
// we can display it in our form again.
request.setAttribute("CollapseKey", collapseKey);
request.setAttribute("Message", userMessage);
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
Since it is a web service, it does not have android_manifest.xml. So permission for internet cannot be added.
If I want to change the host(android.googleapis.com), then how should I do it. (it seems broken).
Have you tried to turn off your firewall? You have to enable gcm ports.
If your organization has a firewall that restricts the traffic to or
from the Internet, you need to configure it to allow connectivity with
GCM. The ports to open are: 5228, 5229, and 5230. GCM typically only
uses 5228, but it sometimes uses 5229 and 5230. GCM doesn't provide
specific IPs, so you should allow your server to accept incoming
connections from all IP addresses contained in the IP blocks listed in
Google's ASN of 15169.
BTW GCM message request is a simple http post, without Message Builder you have to post a message in json format.
Android developer site
More information about message fields

DNS problems on Android

I had gotten reports from a few users that they couldn't login to our app (which makes HTTP calls to our site) or visit our website in their browser, so I added some code to our latest build to check what IP our host name is resolving to. I've gotten reports from several different users now that they get 127.0.0.1 for our hostname when the app starts, which obviously isn't going to work.
They claim they aren't running any proxy software, and this happens on both 2.1 and 2.2. This also happens on both wifi & 3g, which makes me suspect it is some piece of software on their phone that is interfering with DNS resolution somehow. Does anyone know of any popular software that might do that? Or does anyone have any ideas about how to identify which software might be doing it?
Thanks,
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.TXTRecord;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;
public class DNSLookUpActivity extends Activity {
private String url = "https://spectracore.americanlogistics.com/rdac/AdmissionController/CheckMddAdmission";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
funDNS(url);
}
private static void funDNS(String url) {
try {
Lookup lookup = new Lookup(url, Type.ANY);
Record[] records = lookup.run();
if (lookup.getResult() == Lookup.SUCCESSFUL) {
String responseMessage = null;
String listingType = null;
for (int i = 0; i < records.length; i++) {
if (records[i] instanceof TXTRecord) {
TXTRecord txt = (TXTRecord) records[i];
for (Iterator j = txt.getStrings().iterator(); j
.hasNext();) {
responseMessage += (String) j.next();
}
Log.e("TXRecord ", "" + responseMessage);
} else if (records[i] instanceof ARecord) {
listingType = ((ARecord) records[i]).getAddress()
.getHostAddress();
Log.e("ARecord address : ", "" + listingType);
}
}
}
} catch (TextParseException e) {
e.printStackTrace();
}
}
}
Need android ask version 2.3.3 or above
Get their DNS config, and try their DNS servers directly with dig or nslookup. This is not perfect, but it has a good chance of showing you the problem.
dnsjava/org.xbill.DNS is too big for android app, Scott Means's DNSQuery is promiseful:
http://smeans.com/programming/dns-queries-in-java/

Categories

Resources