I'm currently trying to make a settings menu, that will show a MultiSelectListPreference, to select multiple contacts from your contact list.
At this moment, I'm receiving an NullPointerException, when i try to MultiSelectListPreference#setEntryValue(CharSequence[]) If I put the setEntries first, that one throws the same exception.
I've put a breakpoint, to see step by step what happens. The variables are filled because they store Strings, they can contain a String "null", so I guess that it doesn't fail if there is no Display_Name available or so.
I based the findPreference on the example of this answer
Anyone has an idea? If you need more information, tell me. Thanks for reading!
package be.wdk.sendtowork;contactNumberArray
import android.database.Cursor;
import android.os.Bundle;
import android.preference.MultiSelectListPreference;
import android.preference.PreferenceFragment;
import android.provider.ContactsContract;
import android.util.Log;
import android.widget.Toast;
public class PreferenceClass extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Integer countContacts = 0;
String[] projection = new String[]{
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.PHOTO_URI
};
String selection = ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER;
String sortOrder = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME;
try {
Cursor c1 = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, selection, null, sortOrder);
c1.moveToFirst();
Integer c1columncount = c1.getColumnCount();
Integer c1count = c1.getCount();
Toast toastje = Toast.makeText(getActivity(), c1columncount.toString() + " - " + c1count.toString(), Toast.LENGTH_SHORT);
toastje.show();
CharSequence[] contactNameArray = new CharSequence[c1count], contactNumberArray = new CharSequence[c1count];
MultiSelectListPreference mslp = (MultiSelectListPreference) findPreference("contactList");
do {
contactNameArray[countContacts] = c1.getString(0) + " - " + c1.getString(2);
contactNumberArray[countContacts] = c1.getString(1);
countContacts += 1;
} while(c1.moveToNext());
mslp.setEntryValues(contactNumberArray); //<- line that throws the error
mslp.setEntries(contactNameArray);
addPreferencesFromResource(R.xml.preferences);
}
catch (Exception e) {
Log.v("TAG", " " + e.toString());
e.getMessage();
}
}
}
EDIT: Ok, I did a couple more checks.
-I made a test preference in my XML and used the findPrefence to make an object of it to work with -> returns NULL
-I have set my key of my MultiSelectListPreference to #string/test, putted this in my strings.xml, findpreference still returns Null.
Can there be a problem with my PreferenceFragment?
Ok, i found what my problem was.
MultiSelectListPreference mslp = (MultiSelectListPreference) findPreference("contactList");
returns NULL because
addPreferencesFromResource(R.xml.preferences);
is not done at the start... so it didn't load my preferences in yet.
You can solve this using
getFragmentManager().executePendingTransactions();
before
findPreference(section);
In my case, I was trying to use findPreferences in onCreate of the enclosing PreferenceActivity. I moved it down to onCreate of the PreferenceFragment and it works fine.
You can solve this by placing the all the content access functions inside the following
fragment callback
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//Access the content here.
}
Related
I'm am fairly new to Android, and I'm trying to develop an app for a small project of mine using an example Bluetooth Chat App and Spotify Media Notifications. I could not provide the links because stack overflow did not let me but they are available online with a quick google search. I was wondering why I was getting this exception and is there any solution to this?
java.lang.NullPointerException
The line numbers correspond to each of the pieces of code below:
Line 269 if (message.length() > 0)
Line 56 public class BluetoothChatFragment extends Fragment
Line 131 sendMessage(artistName);
How my code is set up:
I have a static broadcast receiver set up exactly like the Spotify link below. I grab the song name and artist and package them into strings. Then I have another broadcast receiver in my Bluetooth fragment. I used another one because I did not know how to get the string into the Bluetooth fragment because I needed to call sendMessage() a private method in the fragment class. It seems like the exception is throwing when I call sendMessage(string) in my fragment.
Static Spotify Broadcast Receiver
package com.example.android.bluetoothchat;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.example.android.common.logger.Log;
public class MyBroadcastReceiver extends BroadcastReceiver {
static final class BroadcastTypes {
static final String SPOTIFY_PACKAGE = "com.spotify.music";
static final String PLAYBACK_STATE_CHANGED = SPOTIFY_PACKAGE + ".playbackstatechanged";
static final String QUEUE_CHANGED = SPOTIFY_PACKAGE + ".queuechanged";
static final String METADATA_CHANGED = SPOTIFY_PACKAGE + ".metadatachanged";
}
#Override
public void onReceive(Context context, Intent intent) {
// This is sent with all broadcasts, regardless of type. The value is taken from
// System.currentTimeMillis(), which you can compare to in order to determine how
// old the event is.
long timeSentInMs = intent.getLongExtra("timeSent", 0L);
Intent sendBack = new Intent("Received");
String action = intent.getAction();
String artistName;
String trackName;
if (action.equals(BroadcastTypes.METADATA_CHANGED)) {
artistName = intent.getStringExtra("artist");
trackName = intent.getStringExtra("track");
String msg = "S a " + artistName + '\0';
String msg2 = "S n " + trackName + '\0';
Log.d("Song", msg);
Log.d("Artist", msg2);
sendBack.putExtra("Song", msg);
sendBack.putExtra("Artist", msg2);
} else if (action.equals(BroadcastTypes.PLAYBACK_STATE_CHANGED)) {
boolean playing = intent.getBooleanExtra("playing", false);
// Do something with extracted information
if(playing) {
Log.d("Playing", "S p\0");
sendBack.putExtra("Playing", "S p\0");
}
else {
Log.d("Playing", "S s\0");
sendBack.putExtra("Playing", "S s\0");
}
}
context.sendBroadcast(sendBack);
}
}
Broadcast Receiver in Fragment:
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String artistName = intent.getStringExtra("Song");
String trackName = intent.getStringExtra("Artist");
String playing = intent.getStringExtra("Playing");
Log.d("Please", artistName);
Log.d("Please", trackName);
Log.d("Please", playing);
sendMessage(artistName);
sendMessage(trackName);
sendMessage(playing);
}
};
sendMessage Method():
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
Any help would be much appreciated!
http://developer.android.com/samples/BluetoothChat/index.html
To me it looks like sendMessage gets called with null instead of an actual string. Note that intent.getStringExtra(some_string) can return null, if some_string cannot be found.
I'd like to use the static String getLastOutgoingCall() method in order to pull the duration of the last outgoing phone call but I don't know how !
I'm a beginner with java programming (I usually program in c++)
The tutorials that I found use the ancient APIs and none of them use the method I'm talking about.
I hope I have not misinterpreted your question. If so, please let me know.
The method String getLastOutgoingCall (Context context) from android.provider.CallLog.Calls, according to the documentation, returns
The last phone number dialed (outgoing) or an empty string if none
exist yet.
So, you can't retrieve the last outgoing call duration using that method.
To get the last outgoing call duration, you can query the CallLog.Calls.CONTENT_URI to retrieve this info.
You can use a method like this:
public String getLastOutgoingCallDuration(final Context context) {
String output = null;
final Uri callog = CallLog.Calls.CONTENT_URI;
Cursor cursor = null;
try {
// Query all the columns of the records that matches "type=2"
// (outgoing) and orders the results by "date"
cursor = context.getContentResolver().query(callog, null,
CallLog.Calls.TYPE + "=" + CallLog.Calls.OUTGOING_TYPE,
null, CallLog.Calls.DATE);
final int durationCol = cursor
.getColumnIndex(CallLog.Calls.DURATION);
// Retrieve only the last record to get the last outgoing call
if (cursor.moveToLast()) {
// Retrieve only the duration column
output = cursor.getString(durationCol);
}
} finally {
// Close the resources
if (cursor != null) {
cursor.close();
}
}
return output;
}
Note: To perform this query you will need to add the following permission to your manifest:
<uses-permission android:name="android.permission.READ_CALL_LOG" />
Edit based on your own answer:
You need to call the getLastOutgoingCallDuration() on the onCreate() method of your Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // Here you need to set the name of your xml
TextView displayDuration;
displayDuration = (TextView) findViewById(R.id.textView2);
String duration = getLastOutgoingCallDuration(this);
displayDuration.setText(output + "sec");
}
Having figured out how to use the wait() and notify() in Java application to fetch some data from the Internet, I had to migrate that code into my Android application. As it turns out the code that would've worked in Java app would never had worked within my Android app even with attempts to make it multi-threaded (with Runnable and then ASyncTask). The problem seems that the Android app will hang after a call on Object.wait() and will never continue further.
The following is the code of the Java & Android classes:
Java
import java.util.Map;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
public class Getter {
private String username = "jdk17";
private String userFullname;
private Object userObj = new Object();
public static void main(String[] args) {
System.out.println("Main");
String text;
Getter main = new Getter();
text = main.getString();
System.out.println("Main - Text = " + text);
}
public String getString() {
Firebase firebaseRef = new Firebase(
"https://demoandroid.firebaseio.com/user/username/" + username);
firebaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onCancelled(FirebaseError arg0) {
}
#Override
public void onDataChange(DataSnapshot snap) {
System.out.println("***********onDataChange()***********");
Object obj = snap.getValue();
userFullname = (String) ((Map) obj).get("fullname");
System.out.println("********* The text = " + userFullname);
synchronized (userObj) {
userObj.notify();
}
}
});
try {
synchronized (userObj) {
System.out.println("Calling wait()");
userObj.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("getString() returning text = " + userFullname);
return userFullname;
}
}
Android
package com.example.paabooking;
import java.util.Map;
import android.util.Log;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
public class FirebaseHelper {
private final String TAG = "FirebaseHelper";
private String username = "jdk17";
private String userFullname;
private Object userObj = new Object();
public FirebaseHelper() {}
public String getString() {
Log.d(TAG, "getString()");
Firebase firebaseRef = new Firebase("https://demoandroid.firebaseio.com/user/username/" + username);
firebaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onCancelled(FirebaseError arg0) {Log.d(TAG, "cancelled.");}
#Override
public void onDataChange(DataSnapshot snap) {
Log.d(TAG, "***********onDataChange()***********");
// TODO Auto-generated method stub
Object obj = snap.getValue();
userFullname = (String)((Map)obj).get("fullname");
Log.d(TAG, "********* The text = " + userFullname);
synchronized(userObj) {
userObj.notify();
}
}
});
try {
synchronized (userObj) {
Log.d(TAG, "Calling wait()");
userObj.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
Log.d(TAG,"getString() returning text = " + userFullname);
return userFullname;
}
}
Console printout:Java
Main
Calling wait()
***********onDataChange()***********
********* The text = Tom Barry
getString() returning text = Tom Barry
Main - Text = Tom Barry
Console printout: Android
getString()
Calling wait()
Java Firebase Library - https://www.firebase.com/docs/java-quickstart.html
I don't think that this is due to any differences (real or hypothetical) between wait/notify in Java and Android.
I think that the difference is explained by this quote from the Firebase page you linked to:
"By default, on Android, all callbacks are executed on the main thread. On other JVM targets, callbacks are executed on a new, separate thread. You can configure this behavior by providing your own EventTarget to the default Config used by the library.".
In the Android case, your main thread appears to be instantiating the Firebase object, adding the listener, and then calling wait(). But wait() is blocking the main thread ... so, of course the main thread is not in a position to accept the callback that would wake it up. Hence, everything freezes.
The 2nd sentence of the quote seems to suggest the way to solve the problem.
I've never come across Firebase before, let alone tried to use it. This is just based on my superficial reading of the documentation and your code.
A month ago, I dropped-in ActionBarSherlock 4.2 into my project. I got everything to work, except the search suggestions for my SearchView. The way I was creating search suggestions was using the method in the Android documentation.
Does ActionBarSherlock support search suggestions? I tried to dig through the issue list on the Github page but the issue seems closed but I can't seem to follow the discussion and understand whether it really is a resolved or not. I thought that some of you who've been using ActionBarSherlock might know better.
It doesn't. But I have found a way to make it query your ContentProvider.
I looked into the source of SuggestionsAdapter from API 17 where the query executes and got an idea of replacing this method. Also I found that ActionbarSherlock's SuggestionsAdapter does not use your SearchableInfo.
Edit com.actionbarsherlock.widget.SuggestionsAdapter in your ActionBarSherlock project:
Add a line
private SearchableInfo searchable;
in constructor, add
this.searchable = mSearchable;
Replace getSuggestions method with this one:
public Cursor getSuggestions(String query, int limit) {
if (searchable == null) {
return null;
}
String authority = searchable.getSuggestAuthority();
if (authority == null) {
return null;
}
Uri.Builder uriBuilder = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.query("") // TODO: Remove, workaround for a bug in Uri.writeToParcel()
.fragment(""); // TODO: Remove, workaround for a bug in Uri.writeToParcel()
// if content path provided, insert it now
final String contentPath = searchable.getSuggestPath();
if (contentPath != null) {
uriBuilder.appendEncodedPath(contentPath);
}
// append standard suggestion query path
uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);
// get the query selection, may be null
String selection = searchable.getSuggestSelection();
// inject query, either as selection args or inline
String[] selArgs = null;
if (selection != null) { // use selection if provided
selArgs = new String[] { query };
} else { // no selection, use REST pattern
uriBuilder.appendPath(query);
}
if (limit > 0) {
uriBuilder.appendQueryParameter("limit", String.valueOf(limit));
}
Uri uri = uriBuilder.build();
// finally, make the query
return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
}
Now it queries my ContentProvider but crashes with default adapter saying that no layout_height loading some xml file from support library. So you have to use custom SuggestionsAdapter. This is what worked for me:
import com.actionbarsherlock.widget.SearchView;
import android.app.SearchManager;
import android.app.SearchableInfo;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public final class DrugsSearchAdapter extends CursorAdapter
{
private static final int QUERY_LIMIT = 50;
private LayoutInflater inflater;
private SearchView searchView;
private SearchableInfo searchable;
public DrugsSearchAdapter(Context context, SearchableInfo info, SearchView searchView)
{
super(context, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
this.searchable = info;
this.searchView = searchView;
this.inflater = LayoutInflater.from(context);
}
#Override
public void bindView(View v, Context context, Cursor c)
{
String name = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
TextView namet = (TextView) v.findViewById(R.id.list_item_drug_name);
namet.setText(name);
String man = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2));
TextView manuf = (TextView) v.findViewById(R.id.list_item_drug_manufacturer);
manuf.setText(man);
}
#Override
public View newView(Context arg0, Cursor arg1, ViewGroup arg2)
{
return this.inflater.inflate(R.layout.list_item_drug_search, null);
}
/**
* Use the search suggestions provider to obtain a live cursor. This will be called
* in a worker thread, so it's OK if the query is slow (e.g. round trip for suggestions).
* The results will be processed in the UI thread and changeCursor() will be called.
*/
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
String query = (constraint == null) ? "" : constraint.toString();
/**
* for in app search we show the progress spinner until the cursor is returned with
* the results.
*/
Cursor cursor = null;
if (searchView.getVisibility() != View.VISIBLE
|| searchView.getWindowVisibility() != View.VISIBLE) {
return null;
}
try {
cursor = getSuggestions(searchable, query, QUERY_LIMIT);
// trigger fill window so the spinner stays up until the results are copied over and
// closer to being ready
if (cursor != null) {
cursor.getCount();
return cursor;
}
} catch (RuntimeException e) {
}
// If cursor is null or an exception was thrown, stop the spinner and return null.
// changeCursor doesn't get called if cursor is null
return null;
}
public Cursor getSuggestions(SearchableInfo searchable, String query, int limit) {
if (searchable == null) {
return null;
}
String authority = searchable.getSuggestAuthority();
if (authority == null) {
return null;
}
Uri.Builder uriBuilder = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.query("")
.fragment("");
// if content path provided, insert it now
final String contentPath = searchable.getSuggestPath();
if (contentPath != null) {
uriBuilder.appendEncodedPath(contentPath);
}
// append standard suggestion query path
uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);
// get the query selection, may be null
String selection = searchable.getSuggestSelection();
// inject query, either as selection args or inline
String[] selArgs = null;
if (selection != null) { // use selection if provided
selArgs = new String[] { query };
} else { // no selection, use REST pattern
uriBuilder.appendPath(query);
}
if (limit > 0) {
uriBuilder.appendQueryParameter("limit", String.valueOf(limit));
}
Uri uri = uriBuilder.build();
// finally, make the query
return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
}
}
And set this adapter in SearchView
searchView.setSuggestionsAdapter(new DrugsSearchAdapter(this, searchManager.getSearchableInfo(getComponentName()), searchView));
I'm the one that opened the github issue for this. It is working on the dev branch. The current version (4.2) doesn't have the fix. It was completely fixed by this commit, but I would suggest just checking out the dev branch and trying it.
I don't know if I'm wrong here or I changed something on accident, but the above answer does not work and the ActionBarSherlock SuggestionsAdapter does not work. All I get are null pointers in runQueryOnBackgroundThread. It never goes into bindView etc. either, yet it manages to display suggestion results. I think android.app.SearchManager is somehow overriding ABS with getSuggestions() but I'm not sure. I'm still trying things out...
I currently have a piece of code in my Android application that picks up the devices IMEI and sends that IMEI as a parameter to a PHP script that is hosted on the Internet.
The PHP script then takes the IMEI parameter and checks a file to see if the IMEI exists in the file, if it does I want to be able to let my Android application know that the IMEI exists. So essentially I just want to be able to return True to my application.
Is this possible using PHP?
Here is my code so far:
Android/Java
//Test HTTP Get for PHP
public void executeHttpGet() throws Exception {
BufferedReader in = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI("http://testsite.com/" +
"imei_script.php?imei=" + telManager.getDeviceId()
));
HttpResponse response = client.execute(request);
in = new BufferedReader
(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String page = sb.toString();
System.out.println(page);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The above sends the IMEI as a parameter to the PHP script which picks it up successfully and runs a check against the file successfully, however I neeed to then be able to send a positive response back from the PHP script if the IMEI matches one in the file.
Here is the PHP:
<?php
// to return plain text
header("Content-Type: plain/text");
$imei = $_GET["imei"];
$file=fopen("imei.txt","r") or exit("Unable to open file!");
while(!feof($file))
{
if ($imei==chop(fgets($file)))
echo "True";
}
fclose($file);
?>
So instead of echo True I want to be able to let my application know that the IMEI was found, is this possible and if so what should I be using to achieve it?
this is good stuff! actually, you're nearly there. your php shouldn't change, your java should! you just need to check the result of the response inside your java code. redeclare your java method as
public String executeHttpGet() {
then, let this method return the variable page.
now you can create a helper method somewhere. if you put it in the same class as executeHttpGet, it will look like this:
public boolean imeiIsKnown(){
return executeHttpGet().equals("True");
}
now you can call this method to find out if your imei is known in your php backend.
I'm not sure is it good for you or not - but you can use headers. If the IMEI was found you can send header("Status: HTTP/1.1 200 OK") otherwise send header("Status: 404 Not Found").
And then you should check response status in your application.
your code is basically sound, all you need to do is tweak it up a bit. i mixed and matched the answers above, because i needed to accomplish exactly what you were trying to. i created a database, instead of checking txt files.
CREATE TABLE IF NOT EXISTS `user_device` (
`Id_User_Device` int(11) NOT NULL auto_increment,
`Nr_User_Device` varchar(60) collate utf8_bin NOT NULL,
`Ic_User_Device_Satus` int(11) NOT NULL default '1',
PRIMARY KEY (`Id_User_Device`),
KEY `Nr_User_Device` (`Nr_User_Device`,`Ic_User_Device_Satus`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=20 ;
the java android code would be (dont forget to create the proper adjustements in the main.xml layout file, inserting 2 elements to a classical helloworld screen:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class ZdeltestEMEIActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DeviceUuidFactory deviceUuidFactory = new DeviceUuidFactory(this);
String deviceUuid = deviceUuidFactory.getDeviceUuid().toString();
Log.d("tgpost",deviceUuid);
try {
String webPostAnswer = deviceIdCheck(deviceUuid);
if (webPostAnswer != null) {
TextView tv1 = (TextView) findViewById(R.id.textdisplay01);
TextView tv2 = (TextView) findViewById(R.id.textdisplay02);
tv1.setText(webPostAnswer);
tv2.setText(deviceUuid);
Log.d("tgpost", "okok "+webPostAnswer);
} else {
Log.d("tgpost", "nono empty");
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.i("tgpost", "exc " + e.getMessage());
Log.i("tgpost", e.toString());
Log.e("tgpost", e.getStackTrace().toString());
e.printStackTrace();
}
}
public String deviceIdCheck(String deviceUuidIn) throws Exception {
boolean flagOK = false;
BufferedReader in = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
Log.v("tgpost", "okok");
//"imei_script.php?deviceId="; + telManager.getDeviceId()
request.setURI(new URI("http://www.you.net/" +
"deviceIdCheck.php?deviceId=" + deviceUuidIn
));
HttpResponse response = client.execute(request);
Log.d("tgpost", "php answered> "+response);
in = new BufferedReader
(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String page = sb.toString();
Log.d("tgpost", "php answered HUMAN> "+page);
return page;
} catch (Exception e) {
return "problems with connection "+e.getMessage();
}
}
}
with an addtional class
import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
public class DeviceUuidFactory {
protected static final String PREFS_FILE = "device_id.xml";
protected static final String PREFS_DEVICE_ID = "device_id";
protected static UUID uuid;
public DeviceUuidFactory(Context context) {
if( uuid ==null ) {
synchronized (DeviceUuidFactory.class) {
if( uuid == null) {
final SharedPreferences prefs = context.getSharedPreferences( PREFS_FILE, 0);
final String id = prefs.getString(PREFS_DEVICE_ID, null );
if (id != null) {
// Use the ids previously computed and stored in the prefs file
uuid = UUID.fromString(id);
} else {
final String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
// Use the Android ID unless it's broken, in which case fallback on deviceId,
// unless it's not available, then fallback on a random number which we store
// to a prefs file
try {
if (!"9774d56d682e549c".equals(androidId)) {
uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
} else {
final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();
uuid = deviceId!=null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) : UUID.randomUUID();
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
// Write the value out to the prefs file
prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();
}
}
}
}
}
/**
* Returns a unique UUID for the current android device. As with all UUIDs, this unique ID is "very highly likely"
* to be unique across all Android devices. Much more so than ANDROID_ID is.
*
* The UUID is generated by using ANDROID_ID as the base key if appropriate, falling back on
* TelephonyManager.getDeviceID() if ANDROID_ID is known to be incorrect, and finally falling back
* on a random UUID that's persisted to SharedPreferences if getDeviceID() does not return a
* usable value.
*
* In some rare circumstances, this ID may change. In particular, if the device is factory reset a new device ID
* may be generated. In addition, if a user upgrades their phone from certain buggy implementations of Android 2.2
* to a newer, non-buggy version of Android, the device ID may change. Or, if a user uninstalls your app on
* a device that has neither a proper Android ID nor a Device ID, this ID may change on reinstallation.
*
* Note that if the code falls back on using TelephonyManager.getDeviceId(), the resulting ID will NOT
* change after a factory reset. Something to be aware of.
*
* Works around a bug in Android 2.2 for many devices when using ANDROID_ID directly.
*
* #see http://code.google.com/p/android/issues/detail?id=10603
*
* #return a UUID that may be used to uniquely identify your device for most purposes.
*/
public UUID getDeviceUuid() {
return uuid;
}
}
on the php side:
<?php
// to return plain text
// header("Content-Type: plain/text");
include('/home/public_html/ConnStrDB.php');
$deviceId = $_GET["deviceId"];
$sql = "SELECT Nr_User_Device FROM user_device WHERE Nr_User_Device = '".$deviceId."'";
$result = mysql_query($sql);
if ($result) {
$row = mysql_fetch_array($result);
if ($row[0]) {$deviceIdFile = $row[0];} else {$deviceIdFile = "device not found";}
} else {
$deviceIdFile = "no check was made, empty set";
}
echo $_GET["deviceId"]." ".$deviceIdFile;
?>
and (so that you dont have to insert the numbers manually (just change the php fileName in the submit):
<?php
// to return plain text
// header("Content-Type: plain/text");
include('/home/public_html/ConnStrDB.php');
$deviceId = $_GET["deviceId"];
$sql = "SELECT Nr_User_Device, Ic_User_Device_Status FROM user_device WHERE Nr_User_Device = ".$deviceId;
$sql = "INSERT INTO user_device (Nr_User_Device) VALUES ('".$deviceId."')";
$result = mysql_query($sql);
if ($result) {
$deviceIdFile = "device inserted";
} else {
$deviceIdFile = "not inserted";
}
echo $_GET["deviceId"]." ".$deviceIdFile;
?>
if succesful, your mobile screen will display the imei 3 times (the one on the device, the one received in php and the one retrieved on the database).
ConnStrDB.php is a file that contains your complete connection to MySQL database.
if you reply with long text, the android application will receive it, as well as the verbose version of any php warning. if you dont need json, you can answer any xml thru a php echo. thanx for your question, very useful! and thanx for the EXCELLENT answers!