I want when user choose from listview an item (Brand name device),load data arrays with integers. I try to make a remote control.The application must load arrays for power,channel up,down,vol up,vol down functions.How i can do this?I have one listview(devices) and buttons power,Volume,Channel.
Every button use one array with integers for IR pulses.
private OnClickListener btnSendChanUpListener = new OnClickListener() {
public void onClick(View v) {
if(run==0) {
run = 1;
new Thread(new Runnable() {
public void run() {
int[] mod1ChanUpX1 = {346,173,......};//Channel up X1 device
try {
SendIRcommand( frequency, mod1ChanUpX1 );
}
catch(Exception e) {
Log.e( "Error transmitting...");
}
run=0;
}}).start();
}
}
};
Related
I use Looper.prepare and Looper.loop in Runnable's run function. But the problem is that the thread not loop at all, the Runnable just run one time. In Activity1, I use three Runnable threads, all looping. Two threads get Data and pictures from net constantly through "while" loop(needn't update UI), one thread select data and pic from local sqlite constantly through "Looper". The data is:
protected void onCreate(Bundle savedInstanceState) {
......
new Thread(getMessageTask).start();
getMessageHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
i++;
System.out.println("niuanmata" + i); //one appear the first one
try {
ArrayList<Map<String, String>> listMessages = (ArrayList<Map<String, String>>)msg.obj;
boolean listchange = true;
if (oldMessages.size() != 0) {
if (listMessages.size() == oldMessages.size()) {
for (int i = 0; i < listMessages.size(); i++) {
Map<String, String> oldmessage = (Map<String, String>) oldMessages.get(i);
Map<String, String> newmessage = (Map<String, String>) listMessages.get(i);
if ((oldmessage.get("mID") != newmessage.get("mID")) || (oldmessage.get("mainContent") != newmessage.get("mainContent")) || (oldmessage.get("deadLine") != newmessage.get("deadLine"))) {
break;
}
if (i == (listMessages.size() - 1)) {
listchange = false;
}
}
}
}
if (listchange) {
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this, listMessages, R.layout.layout_invites,
new String[]{"mID", "creater", "mainContent", "deadLine", "mtype", "createrLogo"},
new int[]{R.id.tv_list_type, R.id.tv_list_name, R.id.tv_list_inviteword, R.id.tv_list_invitedate, R.id.tv_list_inviteid, R.id.iv_list_logo});
lvMessage.setAdapter(adapter);
oldMessages = listMessages;
}
} catch (Exception e) {
Toast.makeText(MainActivity.this, "wrong: " + e.toString(), Toast.LENGTH_SHORT).show();
return;
}
}
};
......
lvMessage.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) { //when creater click, update the message; when others click, reset the alarm
Toast.makeText(MainActivity.this, "ok" , Toast.LENGTH_SHORT).show();
}
});
}
.........
Runnable synchroDataTask = new Runnable() {
#Override
public synchronized void run() {
//data syschno
while (IOHelper.loopjudge()) {
{
AccountsDB adb = new AccountsDB(MainActivity.this);
String thelastupdate = adb.getLastUpdate(account.getChatNO());
Calendar calendar = IOHelper.StringToCalendar(thelastupdate);
calendar.add(Calendar.MINUTE, -30);
String accountData = synchroDataWebservice(account.getChatNO(), IOHelper.CalendarToString(calendar)); //get the datas of the account synchroly
AccountBLL.saveDBofWebString(accountData, MainActivity.this, account); //use static method to save the DB string as SQLite data
}
}
.........
#Override
public synchronized void run() {
while (IOHelper.loopjudge()) {
......
}
.......
Runnable getMessageTask = new Runnable() {
#Override
public synchronized void run() {
Looper.prepare();
//while (IOHelper.loopjudge() && (!stopThread)) {
MessageDB messagedb = new MessageDB(MainActivity.this);
List<MessageMain> messages = messagedb.getMessageByChatNO(account.getChatNO());
ArrayList<Map<String, String>> listMessages = setMessaageListToMap(messages);
Message msg = Message.obtain();
msg.obj = listMessages;
getMessageHandler.sendMessageDelayed(msg, 1000);
//}
Looper.loop();
}
};
......
In my limited experience with android, I use while to do the Loop in getMessageTask , because the data and UI's listview need to be updated constantly. But the listview can not be clicked. Then change to Looper, but the the UI's listview can't be updated constantly....
The answer is that I misunderstand the meaning of Looper, think the Looper.prepare() and Looper.loop() as the while() loop, then make the mistake.
Looper.prepare() and Looper.loop() just means that this thread can be looped, but I must write while loop or for loop by myself.
I am building a simple game (using Java and android xml) and I want to refresh a TextView with a numeric value as often as possible (let's say 5-10 times a second)
Questions:
Is there a better way to show a numeric value refreshing more than once a second?
How to do it efficiently?
My current code:
void textViewRefresher() {
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(100);
runOnUiThread(new Runnable() {
#Override
public void run() {
DecimalFormat format = new DecimalFormat("#.#");
format.setDecimalSeparatorAlwaysShown(false);
bankValue = bankValue + 0.1 * perSecondValue;
String truncatedBank = format.format(bankValue);
bankText.setText(truncatedBank);
totalValue = totalValue + 0.1 * perSecondValue;
String truncatedTotal = format.format(totalValue);
totalText.setText("Total: " + truncatedTotal);
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
}
I have three strings
String one="Connecting.";
String two="Connecting..";
String three="Connecting...";
I have a textView, what I want is to set text to textview in this order..
one-->two-->three-->one-->two-->three and so on until the process is completed.
I have done it in a for loop based on value i.e
if(value%3==0){
tx.setText(one);
}
else if(value%3==1){
tx.setText(two);
}
else
{
tx.setText(three);
}
This is done inside a thread and it is working well.
But I dont want to rely on "value".. I jst want that until process is completed the text changes in order as mentioned above.
I know it is vague but I am not getting how to do this.
Please if someone can give any hint.
code:
public void startProgress(View view) {
bar.setProgress(0);
tx.setText("Connect");
new Thread(new Task()).start();
}
class Task implements Runnable {
#Override
public void run() {
for (int i = 0; i <= 10; i++) {
final int value = i;
try {
Thread.sleep(500);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
bar.setProgress(value);
String one="Connecting.";
String two="Connecting..";
String three="Connecting...";
if(value%3==0){
tx.setText(one);
}
else if(value%3==1){
tx.setText(two);
}
else
{
tx.setText(three);
}
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
It makes sense to have a counter like value that keeps incrementing. But you could do it a little more simply:
String[] texts = new String[3] {"Connecting.", "Connecting..", "Connecting..."};
int value = 0;
// ...
tx.setText(texts[value]);
value = (value+1)%3;
This way, you don't need your big messy if statement. You will need to find another way of notifying your thread when the job is done, rather than just having a fixed number of iterations.
Use TextSwitcher instead of TextView...It will work
I have created the funf app that only uses basic probe like wifi and simple location.At the moment the data is saved to the sd card by i want themto be save to my remote server.Thanks in advance
public class MainActivity extends Activity implements DataListener {
public static final String PIPELINE_NAME = "default";
private FunfManager funfManager;
private BasicPipeline pipeline;
private WifiProbe wifiProbe;
private SimpleLocationProbe locationProbe;
private CheckBox enabledCheckbox;
private Button archiveButton, scanNowButton;
private TextView dataCountView;
private Handler handler;
private ServiceConnection funfManagerConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
funfManager = ((FunfManager.LocalBinder)service).getManager();
Gson gson = funfManager.getGson();
wifiProbe = gson.fromJson(new JsonObject(), WifiProbe.class);
locationProbe = gson.fromJson(new JsonObject(), SimpleLocationProbe.class);
pipeline = (BasicPipeline) funfManager.getRegisteredPipeline(PIPELINE_NAME);
wifiProbe.registerPassiveListener(MainActivity.this);
locationProbe.registerPassiveListener(MainActivity.this);
// This checkbox enables or disables the pipeline
enabledCheckbox.setChecked(pipeline.isEnabled());
enabledCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (funfManager != null) {
if (isChecked) {
funfManager.enablePipeline(PIPELINE_NAME);
pipeline = (BasicPipeline) funfManager.getRegisteredPipeline(PIPELINE_NAME);
} else {
funfManager.disablePipeline(PIPELINE_NAME);
}
}
}
});
// Set UI ready to use, by enabling buttons
enabledCheckbox.setEnabled(true);
archiveButton.setEnabled(true);
scanNowButton.setEnabled(true);
}
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
funfManager = null;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Forces the pipeline to scan now
scanNowButton = (Button) findViewById(R.id.scanNowButton);
scanNowButton.setEnabled(false);
scanNowButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (pipeline.isEnabled()) {
// Manually register the pipeline
wifiProbe.registerListener(pipeline);
locationProbe.registerListener(pipeline);
} else {
Toast.makeText(getBaseContext(), "Pipeline is not enabled.", Toast.LENGTH_SHORT).show();
}
}
});
// Displays the count of rows in the data
dataCountView = (TextView) findViewById(R.id.dataCountText);
// Used to make interface changes on main thread
handler = new Handler();
enabledCheckbox = (CheckBox) findViewById(R.id.enabledCheckbox);
enabledCheckbox.setEnabled(false);
// Runs an archive if pipeline is enabled
archiveButton = (Button) findViewById(R.id.archiveButton);
archiveButton.setEnabled(false);
archiveButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (pipeline.isEnabled()) {
pipeline.onRun(BasicPipeline.ACTION_ARCHIVE, null);
// Wait 1 second for archive to finish, then refresh the UI
// (Note: this is kind of a hack since archiving is seamless and there are no messages when it occurs)
handler.postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(getBaseContext(), "Archived!", Toast.LENGTH_SHORT).show();
updateScanCount();
}
}, 1000L);
} else {
Toast.makeText(getBaseContext(), "Pipeline is not enabled.", Toast.LENGTH_SHORT).show();
}
}
});
// Bind to the service, to create the connection with FunfManager
bindService(new Intent(this, FunfManager.class), funfManagerConn, BIND_AUTO_CREATE);
}
#Override
public void onDataCompleted(IJsonObject probeConfig, JsonElement checkpoint) {
updateScanCount();
// Re-register to keep listening after probe completes.
wifiProbe.registerPassiveListener(this);
locationProbe.registerPassiveListener(this);
}
#Override
public void onDataReceived(IJsonObject arg0, IJsonObject arg1) {
// TODO Auto-generated method stub
}
private static final String TOTAL_COUNT_SQL = "SELECT count(*) FROM " + NameValueDatabaseHelper.DATA_TABLE.name;
/**
* Queries the database of the pipeline to determine how many rows of data we have recorded so far.
*/
private void updateScanCount() {
// Query the pipeline db for the count of rows in the data table
SQLiteDatabase db = pipeline.getDb();
Cursor mcursor = db.rawQuery(TOTAL_COUNT_SQL, null);
mcursor.moveToFirst();
final int count = mcursor.getInt(0);
// Update interface on main thread
runOnUiThread(new Runnable() {
#Override
public void run() {
dataCountView.setText("Data Count: " + count);
}
});
}
}
For sending data to remote server, first you need to configure your strings.xml
file like below.
"archive": {
"#schedule": {"interval": 60}
},
"upload": {
"url": \"http://example.com/test/android_data_receiver.php\",
"#schedule": {"interval": 60}
}
It will send data to server every 1 minutes and also make sure you have added
permission for accessing remote server to Android manifest file
Code for allowing permission
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
After done the above step please create a server file in your domain, For the
testing purpose I had created a file below. Yo can modify the file as your need.
<?php
$target_path = "uploads/";
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ". basename( $_FILES['uploadedfile']['name'])." has been uploaded";
}
else {
echo "There was an error uploading the file, please try again!";
}
?>
You need a database on server and some backend function to add data to your remote db. The backend function should be on server, and you can call it from your Android app via HttpRequest etc.. Read about REST APIs
I have to refresh my listview every 3 seconds (I'm in ListFragment) so I start a new Thread wich start runOnUiThread to edit UI.
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
new Thread(new Runnable() {
public void run() {
do{
ObjectMapper mapper = new ObjectMapper();
VideoData element = null;
try {
element = mapper.readValue(new URL("http://192.168.4.111:3232/videodata.json").openStream(), VideoData.class);
} catch (Exception e) {
e.printStackTrace();
}
final VideoData newData = element;
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
hd = newData.getChildren().get(0).getChildren().get(id);
vba.notifyDataSetChanged();
}
});
try {
Thread.sleep(3*1000);
} catch (InterruptedException e) {}
}while(true);
}
}).start();
setAdapter();
}
I parse data on web, and update the reference.
private void setAdapter()
{
if(id == 0)
hd = hd.getChildren().get(0);
vba = new ValueBaseAdapter(getActivity(), 0, hd.getChildren());
setListAdapter(vba);
}
I saw that when notifyDataSetChanged is called, getView is called (and it's ok) but I have old reference, the one of when I called setAdapter the first time.
Also If I set null hd in run(), doesn't change anything, listview doesn't change.
Where is the error? Thanks.
It seems that notifyDataSetChanged() updates adapter's data only if you work with List