Unique device id - android

Is there any unique id on Android Mobile?? If it is then how many digit it has?
How can I access that through my program??
Thanks
Deepak

There are several problems that occur when using IMEI, IMSI... that are described here:
http://android-developers.blogspot.pt/2011/03/identifying-app-installations.html
The recommended approach is to use:
http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID
String unique_id = android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);

check IMEI.
http://www.anddev.org/tinytut_-_getting_the_imsi_-_imei_sim-device_unique_ids-t446.html

For detailed instructions on how to get a Unique Identifier for each Android device your application is installed from, see this official Android Developers Blog posting:
http://android-developers.blogspot.com/2011/03/identifying-app-installations.html
It seems the best way is for you to generate one your self upon installation and subsequently read it when the application is re-launched.
I personally find this acceptable but not ideal. No one identifier provided by Android works in all instances as most are dependent on the phone's radio states (wifi on/off, cellular on/off, bluetooth on/off). The others like Settings.Secure.ANDROID_ID must be implemented by the manufacturer and are not guaranteed to be unique.
The following is an example of writing data to an INSTALLATION file that would be stored along with any other data the application saves locally.
public class Installation {
private static String sID = null;
private static final String INSTALLATION = "INSTALLATION";
public synchronized static String id(Context context) {
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists())
writeInstallationFile(installation);
sID = readInstallationFile(installation);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return sID;
}
private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}
private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}

Related

Kotlin access file in project [duplicate]

I have a simple .txt file with just a couple lines in right now, each line has a word then a comma then another word, representing a very simplistic username , password bank. For some reason though I cant get the File to open to read from it.
Here is my code that I'm using....
try {
final String PATH = "src\\main\\assets\\passwords.txt";
Log.w("myApp", "passed");
List<String> user_password = FileUtils.readLines(new File(PATH));
Log.w("myApp", "passed2");
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
Log.w("myApp", parsed[0]);
return new Credentials(parsed[0], parsed[1]);
//return credential;
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
} catch (IOException e) {
System.out.print(e);
Log.w("MyApp", "failed");
}
I've tried putting the passwords.txt file in different places but that doesn't seem to work either.
You're referencing wrong to file in assets folder. It has to be smth like:
file:///android_asset/myfoldername/myfilename
in your particular case it's file:///android_asset/passwords.txt, though you have to keep in mind that it's always read only file
final String PATH = "src\\main\\assets\\passwords.txt";
That's not going to work. Android is not Windows, and an Android device is not your Windows development PC.
First, \ is the Windows path separator. On OS X, Linux, and Android, the path separator is /.
Second, src\main\assets\passwords.txt is a file in your project. It is not a file on the filesystem of the Android device.
To access assets, use AssetManager to open an InputStream(). You can get an AssetManager by calling getAssets() on any handy Context, such as your activity. Then, for your asset, call open("passwords.txt") on the AssetManager to get the InputStream, that you can then use to read in the data.
Thanks to #CommonsWare I was able to achieve what I was trying to do by using InputStream and then also IOUtils to read everything into the List.
try {
InputStream iS = this.getAssets().open("passwords.txt");
List<String> user_password = IOUtils.readLines(iS);
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
return new Credentials(parsed[0], parsed[1]);
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
}catch (IOException e){
System.out.print(e);
}

Android getSerial() not returning the actual serial number or IMEI

I've got this working, I think, but the data coming from the getSerial() request is not accurate.
The result does not match anything in my "about" section of my devices.
I am in need of this information to help my end users when they call into our helpdesk - they need to identify their device by serial number
is there a way to translate the getSerial() to the actual serial numbers?
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
String serialNumber;
serialNumber = android.os.Build.getSerial();
anyone know how to get the actual information?
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
getSystemService is a method from the Activity class. getDeviceID() will return the MDN or MEID of the device depending on which radio the phone uses (GSM or CDMA).
Each device MUST return a unique value here (assuming it's a phone). This should work for any Android device with a sim slot or CDMA radio. You're on your own with that Android powered microwave ;-)
Turns out getting unique hardware identifiers is getting harder and harder, so it's best to plan the application around not having access to these kinds of pieces of information, and instead to create your own.
I read a LOT of articles and tested a lot of code samples, and ultimately stumbled across this gem and find it to be very useful:
Create a Class called Installation:
public static class Installation {
private static String sID = null;
private static final String INSTALLATION = "INSTALLATION";
public synchronized static String id(Context context) {
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists())
writeInstallationFile(installation);
sID = readInstallationFile(installation);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return sID;
}
private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}
private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}
Anywhere in your application that you need that unique ID - just call this to get it - or create it the first time:
//INSTALLATION ID
String installID = Installation.id(this);
Log.w("INSTALLATION_ID", installID);
Super easy
And extensible if you ever need to or want to save anything else unique to your apps installation to the same place.

Failing to open file, am I linking it wrong? Or is Android Studio not seeing it for some reason?

I have a simple .txt file with just a couple lines in right now, each line has a word then a comma then another word, representing a very simplistic username , password bank. For some reason though I cant get the File to open to read from it.
Here is my code that I'm using....
try {
final String PATH = "src\\main\\assets\\passwords.txt";
Log.w("myApp", "passed");
List<String> user_password = FileUtils.readLines(new File(PATH));
Log.w("myApp", "passed2");
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
Log.w("myApp", parsed[0]);
return new Credentials(parsed[0], parsed[1]);
//return credential;
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
} catch (IOException e) {
System.out.print(e);
Log.w("MyApp", "failed");
}
I've tried putting the passwords.txt file in different places but that doesn't seem to work either.
You're referencing wrong to file in assets folder. It has to be smth like:
file:///android_asset/myfoldername/myfilename
in your particular case it's file:///android_asset/passwords.txt, though you have to keep in mind that it's always read only file
final String PATH = "src\\main\\assets\\passwords.txt";
That's not going to work. Android is not Windows, and an Android device is not your Windows development PC.
First, \ is the Windows path separator. On OS X, Linux, and Android, the path separator is /.
Second, src\main\assets\passwords.txt is a file in your project. It is not a file on the filesystem of the Android device.
To access assets, use AssetManager to open an InputStream(). You can get an AssetManager by calling getAssets() on any handy Context, such as your activity. Then, for your asset, call open("passwords.txt") on the AssetManager to get the InputStream, that you can then use to read in the data.
Thanks to #CommonsWare I was able to achieve what I was trying to do by using InputStream and then also IOUtils to read everything into the List.
try {
InputStream iS = this.getAssets().open("passwords.txt");
List<String> user_password = IOUtils.readLines(iS);
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
return new Credentials(parsed[0], parsed[1]);
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
}catch (IOException e){
System.out.print(e);
}

android NetworkOnMainThreadException in googles Credential.refreshToken()

I have an android app, that should use google fusion tables. I'm using a google service account and have to get the path of my xxxxxxxxxxxprivatekey.p12.
public class CredentialProvider {
...
private static String PRIVATE_KEY = "xxxxxxxxxxxprivatekey.p12";
...
public static GoogleCredential getCredential() throws IOException, GeneralSecurityException {
return getCredential(Arrays.asList(SCOPES), SERVICE_ACCOUNT_EMAIL, new File(PRIVATE_KEY), HTTP_TRANSPORT, JSON_FACTORY);
}
...
}
The code wants to make a new File out of the PRIVATE_KEY path. I've tried various paths but every time I'm getting a FileNotFoundException and open failed: ENOENT (No such file or directory).
I have read something about the assets folder, but I don't know how to get that work with the getCredential method.
Where I have to put my private key in my android project and
how has the PRIVATE_KEY path to look like and
how I get "new File(PRIVATE_KEY)" work?
Thanks ;)
EDIT:
now I'm overriding GoogleCredential.Builder to create my own setServiceAccountPrivateKeyFromP12File(InputStream p12File) like in your link and it seems to work fine. But in getCredential() refreshToken() is called and crashes in a NetworkOnMainThreadException.
I've read, that I should use AsyncTask for it. Can you give me a hint, where I have to put that AsyncTask and what should be inside doInBackground() and what inside onPostExecute() or any method?
Here is the code of getCredential(). It crashes in refreshToken() with a NetworkOnMainThreadException:
public static GoogleCredential getCredential(List<String> SCOPE, String SERVICE_ACCOUNT_EMAIL,
InputStream inputStreamFromP12File, HttpTransport HTTP_TRANSPORT, JsonFactory JSON_FACTORY)
throws IOException, GeneralSecurityException {
// Build service account credential.
MyGoogleCredentialBuilder builder = new MyGoogleCredentialBuilder();
builder.setTransport(HTTP_TRANSPORT);
builder.setJsonFactory(JSON_FACTORY);
builder.setServiceAccountId(SERVICE_ACCOUNT_EMAIL);
builder.setServiceAccountScopes(SCOPE);
builder.setServiceAccountPrivateKeyFromP12File(inputStreamFromP12File);
GoogleCredential credential = builder.build();
credential.refreshToken();
return credential;
}
EDIT2:
Finally, I solved it that way:
private static class RefreshTokenTask extends AsyncTask<GoogleCredential, Void, Void> {
#Override
protected Void doInBackground(GoogleCredential... params) {
try {
params[0].refreshToken();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
and in my getCredential method:
new RefreshTokenTask().execute(credential);
You can't access assets as you would access regular files, since these files are bundled with the application.
That's why new File(PRIVATE_KEY) doesn't work, and there is no path you can give that would make it work.
What you could do is get an InputStream for that file :
AssetManager assetManager = context.getAssets();
InputStream input = assetManager.open(PRIVATE_KEY);
If you need to access it as a File, you could copy it to the internal storage of your app the first time your application is launched. I'm not sure that's the best solution (perhaps you don't want to store the private key on the device's internal storage for security reasons), but it should work. Then you can access it from the context.getFilesDir () folder.
InputStream fis = assetManager.open(PRIVATE_KEY);
FileOutputStream fos = openFileOutput(PRIVATE_KEY, Context.MODE_PRIVATE);
byte buf[] = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();

Android application crash when run after installation

i am developing a native android application, i am using a third party api as well. The problem is, when i connect mobile (S3) to my machine and run application directly on mobile then it works fine. But when i copied the APK to android mobile, installed APP and run. Then on one of api call it crashes saying "Unfortunately AppName stopped working".
I could not find any way around to find out that what is the issue and what thing is the cause of application crash.
Anyone please suggest how to find out the problem or what can be the possible cuse. I am developing in Eclipse.
Why don't you set up a 5 minute quick BugSense library and free account and check the exception you get? http://www.bugsense.com/
You can set up your own log writing system via implementing java.lang.Thread.UncaughtExceptionHandler within your app.
e.g.
public class myExceptionHandler implements UncaughtExceptionHandler {
private UncaughtExceptionHandler defaultUEH;
private String localPath;
public myExceptionHandler(String localPath) {
this.localPath = localPath;
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
#Override
public void uncaughtException(Thread t, Throwable e) {
final long ts = new Date().getTime();
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(ts);
final String timestamp = new SimpleDateFormat("HH_mm_ss_SSS")
.format(cal.getTime());
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
e.printStackTrace(printWriter);
String stacktrace = result.toString();
printWriter.close();
String filename = "logcat"+timestamp + ".txt";
if (localPath != null) {
writeToFile(stacktrace, filename);
}
defaultUEH.uncaughtException(t, e);
}
private void writeToFile(String stacktrace, String filename) {
try {
BufferedWriter bos = new BufferedWriter(new FileWriter(localPath
+ "/" + filename));
bos.write(stacktrace);
bos.flush();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Call this handler from the MainActivity like this:
Thread.setDefaultUncaughtExceptionHandler(new myExceptionHandler("Put your target directory/folder path where you would like to store the log file"));
Now you will have a logfile written whenever app crashs with in the folder that you have used in code.
Just connect your device to the PC and let the LogCat window in Eclipse open. Logcat messages will still be outputted to LogCat without actually debugging your app.

Categories

Resources