I am new to Tensorflow and Android, I am trying to classify data from external accelerometer to predict weather it align to left, right, forward , back or center. So I trained model using colab and converted it to tflite and added it to Android App, I could not make any sense of output
package com.yogai.tensorflowlava;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.widget.Toolbar;
import com.yogai.tensorflowlava.ml.Adxl345;
import org.tensorflow.lite.DataType;
import org.tensorflow.lite.TensorFlowLite;
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;
import java.io.IOException;
import java.nio.ByteBuffer;
public class MainActivity extends AppCompatActivity {
Button submitButton;
EditText editText;
String text;
String TAG = "My_APp";
// private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Context context;
editText = findViewById(R.id.editText);
submitButton = findViewById(R.id.submitButton);
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
text = editText.getText().toString().trim();
//String str = "geekss#for#geekss";
// String[] arrOfStr = text.split(",", 3);
//
// // String[] strings = new String[] {"1", "2", "3", "4"};
// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
// Float[] floats = Arrays.stream(arrOfStr).map(Float::valueOf).toArray(Float[]::new);
// }
String[] parts = text.split(",");
float[] numbers = new float[parts.length];
for (int i = 0; i < parts.length; ++i) {
float number = Float.parseFloat(parts[i]);
float rounded = (int) Math.round(number * 1000) / 1000f;
numbers[i] = rounded;
}
// float[][] array2d = new float[1][3];
//
//
//
// for(int j=1;j<4;j++) {
// array2d[1][j] = numbers[j];
//
//
// }
// Float testValue = array2d[1][1]+1;
Log.d(TAG,String.valueOf(numbers[1]));
ByteBuffer.allocate(4).putFloat(numbers[0]).array();
byte[] byteArray= FloatArray2ByteArray(numbers);
ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
getOutput(byteBuffer);
}
});
}
public static byte[] FloatArray2ByteArray(float[] values){
ByteBuffer buffer = ByteBuffer.allocate(4 * values.length);
for (float value : values){
buffer.putFloat(value);
}
return buffer.array();
}
private void getOutput(ByteBuffer byteBuffer) {
try {
Adxl345 model = Adxl345.newInstance(getApplicationContext());
// Creates inputs for reference.
TensorBuffer inputFeature0 = TensorBuffer.createFixedSize(new int[]{1, 3}, DataType.FLOAT32);
inputFeature0.loadBuffer(byteBuffer);
// Runs model inference and gets result.
Adxl345.Outputs outputs = model.process(inputFeature0);
TensorBuffer outputFeature0 = outputs.getOutputFeature0AsTensorBuffer();
String converted = new String(buffer.array(), "UTF-8");
Toast.makeText(this,"output: "+outputFeature0.toString(),Toast.LENGTH_SHORT).show();
// Releases model resources if no longer used.
model.close();
} catch (IOException e) {
// TODO Handle the exception
Toast.makeText(this,"Error: "+ e.toString(),Toast.LENGTH_SHORT).show();
}
}
}
You can use outputFeature0.getDataType().toString() to check the type of the data.
It would return a string among "FLOAT32","INT32","UINT8","INT64","STRING","INT8".
If the type of the data is FLOAT32, you can get the data like below:
float[] data=outputFeature0.getFloatArray()
Related
The below code is certainly not the best way of doing what I need to do but unfortunately I don't have much time to go back and change data structures / storage options etc. It will be cleaned up however. Anyway, the quality of the code isn't my problem, I digress.
When the user registers their account for the first time, they are given a ListView with multiple choice (check boxes). The selected items are stored in a SparseBooleanArray then converted to an ArrayList of Strings.
The names of the ListView items are coming from an SQLite database method called getStoreNames() which returns an ArrayList of Strings of the Store names.
I need to then get the Store objects associated with each store name. This is done in the for loop within the continue_button case. (Store store = db.returnStoreByName(storeName)... then adding each of those stores to an ArrayList of Stores.
I am then trying to store this ArrayList of stores in SharedPreferences. Because SPs doesn't support ArrayLists, the data is serialized. In the next Activity when I try to access the Store objects, I deserialize the shared preference object. However when I checked the size of the deserialized ArrayList, it is 0. I checked the arraylist size before I serialized it and put it into shared preferences and it was giving the correct size.
This leads me to believe that somewhere between serializing/deserializing or storing in/retrieving from shared prefs is where something is going wrong and the arraylist is being emptied.
Here is the first activity where the data is saved to shared prefs.
package com.mad.losesano2;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import org.json.JSONArray;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class StoreListRegisterActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, View.OnClickListener{
ListView list_view;
List<String> stores;
DB db;
ArrayList<String> users_stores;
SharedPreferences sp;
Button continue_button;
ArrayList<Store> stores_objects = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_store_list_register);
list_view = (ListView) findViewById(R.id.list_view);
list_view.setOnItemClickListener(this);
list_view.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
list_view.setItemsCanFocus(false);
continue_button = (Button) findViewById(R.id.continue_button);
continue_button.setOnClickListener(this);
db = new DB(getApplicationContext());
stores = db.getStoreNames();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, stores);
list_view.setAdapter(arrayAdapter);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SparseBooleanArray a = list_view.getCheckedItemPositions();
users_stores = new ArrayList<>();
for (int i = 0; i < stores.size(); i++){
if(a.valueAt(i)){
String store_name = list_view.getAdapter().getItem(a.keyAt(i)).toString();
users_stores.add(store_name);
}
}
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.continue_button:
sp = getSharedPreferences("storeList", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
for (String storeName : users_stores) {
Store store = db.returnStoreByName(storeName);
stores_objects.add(store);
Log.d("LoSeSANO", "Store name: " + store.getName());
try {
editor.putString("usersStores", ObjectSerializer.serialize(stores_objects));
} catch (IOException e) {
e.printStackTrace();
}
}
Log.d("LoSeSANO", "Size: " + stores_objects.size());
Intent intent2 = new Intent(this, LoggedInActivity.class);
startActivity(intent2);
break;
}
}
}
Here is the code where I try to receive the SP object
package com.mad.losesano2;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
public class LoggedInActivity extends AppCompatActivity {
ArrayList<Store> store_list;
SharedPreferences sp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logged_in);
if (null == store_list) {
store_list = new ArrayList<Store>();
}
sp = getSharedPreferences("storeList", MODE_PRIVATE);
try {
store_list = (ArrayList<Store>) ObjectSerializer.deserialize(sp.getString("usersStores", ObjectSerializer.serialize(new ArrayList<Store>())));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Log.d("LoSeSANO", "Store name at index 0: " + store_list.get(0).getName()); //store_list size = 0.
}
}
Lastly, here is the ObjectSerializer class
package com.mad.losesano2;
/**
* Created by oshau on 18/03/2018.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectSerializer {
public static String serialize(Serializable obj) throws IOException {
if (obj == null) return "";
ByteArrayOutputStream serialObj = new ByteArrayOutputStream();
ObjectOutputStream objStream = new ObjectOutputStream(serialObj);
objStream.writeObject(obj);
objStream.close();
return encodeBytes(serialObj.toByteArray());
}
public static Object deserialize(String str) throws IOException, ClassNotFoundException {
if (str == null || str.length() == 0) return null;
ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str));
ObjectInputStream objStream = new ObjectInputStream(serialObj);
return objStream.readObject();
}
public static String encodeBytes(byte[] bytes) {
StringBuffer strBuf = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
}
return strBuf.toString();
}
public static byte[] decodeBytes(String str) {
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < str.length(); i+=2) {
char c = str.charAt(i);
bytes[i/2] = (byte) ((c - 'a') << 4);
c = str.charAt(i+1);
bytes[i/2] += (c - 'a');
}
return bytes;
}
}
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mad.losesano2/com.mad.losesano2.LoggedInActivity}: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
From this Logcat it's clear that your array size is 0 and you are trying to access index 0. Make sure you check array length before accessing its content.
May be you are getting crash for this line
Log.d("LoSeSANO", "Store name at index 0: " + store_list.get(0).getName());
check store_list size before accessing it's index.
I saw u only store a simple List then you didnt easy way to share data.
Okey with small data like this : SparseBooleanArray a = list_view.getCheckedItemPositions();
I will create class
Class A implement Serializable{
List<String> data;
}
then send Serializable via Intent.
My app is trying to make some calculations and checking for a condition and printing the array of numbers which satisfy the condition.But the app is closing on click.Please help..
package com.example.ganesha.app1;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import static android.R.attr.button;
public class MainActivity extends AppCompatActivity {
private Button result;
private EditText cap,pwfac,dis,solution;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
result = (Button) findViewById(R.id.resbut);
cap = (EditText) findViewById(R.id.capacity);
pwfac = (EditText) findViewById(R.id.powerfactor);
dis = (EditText) findViewById(R.id.distance);
solution = (EditText) findViewById(R.id.result);
//mytextview = (TextView)findViewById(R.id.result)
result.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Double capacity = Double.valueOf(cap.getText().toString());
Double powerfactor = Double.valueOf(pwfac.getText().toString());
Double distance = Double.valueOf(dis.getText().toString());
Double amps = capacity / (718.80 * powerfactor);
Double minimum = 24.9;
Double ampspermtr=amps/distance;
Double[] cases = {26.8156, 16.4013, 10.2083, 6.8180, 4.0509, 2.5470, 1.6151, 1.1689, 0.8673, 0.6075, 0.4458, 0.3616, 0.3028, 0.2532, 0.2082, 0.1812, 0.1604, 0.1461, 0.1359};
Double [] volts=new Double[19];
for(int i = 0; i <19; i++)
{
volts[i]=cases[i]*ampspermtr;
}
Double [] wires={1.50,2.50,4.0,6.0,10.0,16.0,25.0,35.0,50.0,70.0,95.0,120.0,150.0,185.0,240.0,300.0,400.0,500.0,630.0};
final Double [] allpossible = new Double[19];
int c=0;
for(int j=0;j<19;j++)
{
if(volts[j]<minimum)
{
allpossible[c]=wires[j];
}
c++;
}
final int g= c;
for(int p=0;p<g;p++)
{
String value = Double.toString(allpossible[g]);
solution.append(value);
}
}
});
It is based on electrical Engineering.Can someone find the mistake and help me out
Actually there some Exception occurred in you calculation in
OnClick of Button you should write the Calculation code surround
with try catch block like Below
try{
Double capacity = Double.valueOf(cap.getText().toString());
Double powerfactor = Double.valueOf(pwfac.getText().toString());
Double distance = Double.valueOf(dis.getText().toString());
Double amps = capacity / (718.80 * powerfactor);
Double minimum = 24.9;
Double ampspermtr=amps/distance;
Double[] cases = {26.8156, 16.4013, 10.2083, 6.8180, 4.0509, 2.5470, 1.6151, 1.1689, 0.8673, 0.6075, 0.4458, 0.3616, 0.3028, 0.2532, 0.2082, 0.1812, 0.1604, 0.1461, 0.1359};
Double [] volts=new Double[19];
for(int i = 0; i <19; i++)
{
volts[i]=cases[i]*ampspermtr;
}
Double [] wires={1.50,2.50,4.0,6.0,10.0,16.0,25.0,35.0,50.0,70.0,95.0,120.0,150.0,185.0,240.0,300.0,400.0,500.0,630.0};
final Double [] allpossible = new Double[19];
int c=0;
for(int j=0;j<19;j++)
{
if(volts[j]<minimum)
{
allpossible[c]=wires[j];
}
c++;
}
final int g= c;
for(int p=0;p<g;p++)
{
String value = Double.toString(allpossible[g]);
solution.append(value);
}
}
}Catch(Exception ex){
// handle your Exception here
}
I got my app to read an app and then tell me what the code says, but now I'm trying to have it encode the string back into a barcode and display it as an image on the screen. However, it always force closes the app before it starts. Here is my code, please help:
import java.util.EnumMap;
import java.util.Map;
import android.os.Bundle;
import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.view.Gravity;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
public class Main extends Activity {
IntentIntegrator integrator = new IntentIntegrator(this);
private static final int WHITE = 0xFFFFFFFF;
private static final int BLACK = 0xFF000000;
LinearLayout myLayout = (LinearLayout)findViewById(R.id.myLayout);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//LinearLayout myLayout = (LinearLayout)findViewById(R.id.myLayout);
Button btn =(Button)findViewById(R.id.button1);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
integrator.initiateScan();
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanResult != null) {
Toast.makeText(Main.this,
"works",
Toast.LENGTH_SHORT).show();
String contents = intent.getStringExtra("SCAN_RESULT");
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
Toast.makeText(Main.this,
contents,
Toast.LENGTH_SHORT).show();
Bitmap bitmap = null;
ImageView iv = new ImageView(this);
try {
bitmap = encodeAsBitmap(contents, BarcodeFormat.CODE_128, 600, 300);
iv.setImageBitmap(bitmap);
} catch (WriterException e) {
e.printStackTrace();
}
myLayout.addView(iv);
TextView tv = new TextView(this);
tv.setGravity(Gravity.CENTER_HORIZONTAL);
tv.setText(contents);
myLayout.addView(tv);
}
}
Bitmap encodeAsBitmap(String contents, BarcodeFormat format, int img_width, int img_height) throws WriterException {
String contentsToEncode = contents;
if (contentsToEncode == null) {
return null;
}
Map<EncodeHintType, Object> hints = null;
hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix result;
try {
result = writer.encode(contentsToEncode, format, img_width, img_height, hints);
} catch (IllegalArgumentException iae) {
// Unsupported format
return null;
}
int width = result.getWidth();
int height = result.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
#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;
}
}
IntentResult and IntentIntegrator are both from ZXing.
Log Cat:
03-15 13:05:04.303: E/AndroidRuntime(4363): FATAL EXCEPTION: main
In your toast, instead of Main.this you should try getApplicationContext(). Also recall that an Activity is a type of Context.
Try to move this:
LinearLayout myLayout = (LinearLayout)findViewById(R.id.myLayout);
under:
setContentView(R.layout.main);
We are building an app that is supposed to do several things based on an input text file. First it parses the data in the text file and extracts the useful information and builds a linkedList. The Linked List is a group of BinaryBlock objects. From there we want to dynamically graph the getwfs() function of the BinaryBlocks. At this point, we have got the graph somewhat working but instead of graphing over time it graphs in one big clump and scrolls all the way to the end.
BinaryBlock is listed here:
This is fully tested and functional and really only important in the larger context of the program:
// BinaryBlock.java
public class BinaryBlockLite {
private int pwda[], wfs[];
String lineData;
public BinaryBlockLite( String data ){ // class constructor
lineData = data;
pwda = new int[5];
wfs = new int[4];
setWfs();
}//end constructor
public String WfsToString(){
if (wfs.length == 0)
return "";
String data = "Channel 2: ";
for(int i = 0; i < wfs.length; ++i ){
data = data + "wfs[" + i + "]=" + wfs[i] + " ";
}
return data + "\n";
}
//===========================================================
// Setters
//=============================================================
//read the 5 individual bytes of the Pwda from LineData and into the pwda[] array
private void setPwda(){
int location = 13;
for(int i = 0; i < 5; ++i){
String temp = "" + lineData.charAt(++location) + lineData.charAt(++location);
pwda[i] = Integer.parseInt(temp, 16);
}
}
//logically manipulate the 5 bytes of the PWDA into 4 10-bit WFSs
private void setWfs(){
setPwda();
int j = 0;
for (int i = 0; i < 4; ++i){
wfs[i] = ((pwda[j] << 2) | (( pwda[j + 1] >> 6) & 0x03)) & 0x03ff;
wfs[++i] = ((pwda[j + 1] << 4) | (( pwda[j + 2] >>> 4) & 0x0f)) & 0x03ff;
wfs[++i] = ((pwda[j + 2] << 6) | (( pwda[j + 3] >>> 2) & 0x3f)) & 0x03ff;
wfs[++i] = ((pwda[j + 3] << 8) | (( pwda[j + 4] >>> 0) & 0xff)) & 0x03ff;
}
}
//===========================================================
// Getters
//=============================================================
public int[] getPwda(){
return pwda;
}
public int[] getWfs(){
return wfs;
}
}//end BinaryBlock Class
The main harness is listed here:
The problem is simply that instead of repainting each time and graphing it across the screen, it graphs all of the point at one time.
//MainActivity.java
import android.os.Bundle;
import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Color;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import com.smith.fsu.wave.BinaryBlockLite;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.ListIterator;
import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
public class MainActivity extends Activity {
public static LinkedList<BinaryBlockLite> list;
Button btnMain;
Boolean fileLoaded = false;
int xTick = 0,
lastMinX = 0;
Context context = this;
//
////////////////////////////////////////////////////////////////
//import test
private XYMultipleSeriesDataset WFDataset = new XYMultipleSeriesDataset();
private XYMultipleSeriesRenderer WaveFormRenderer = new XYMultipleSeriesRenderer();
private XYSeries WFCurrentSeries;
private GraphicalView WFChartView;
//////////////////////////////////////////////////////////////////////////
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new LinkedList<BinaryBlockLite>();
btnMain=(Button)findViewById(R.id.btnMain);
WaveFormRenderer.setAxisTitleTextSize(16);
WaveFormRenderer.setChartTitleTextSize(20);
WaveFormRenderer.setLabelsTextSize(15);
WaveFormRenderer.setLegendTextSize(15);
WaveFormRenderer.setMargins(new int[] {20, 30, 15, 0});
WaveFormRenderer.setAxesColor(Color.YELLOW);
String seriesTitle = "Input Data";
XYSeries series = new XYSeries(seriesTitle);
WFDataset.addSeries(series);
WFCurrentSeries = series;
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setColor(Color.GREEN);
WaveFormRenderer.addSeriesRenderer(renderer);
WaveFormRenderer.setXAxisMin(0.0);
WaveFormRenderer.setXAxisMax(500);
// renderer.setFillBelowLine(true) ;
// renderer.setFillBelowLineColor(Color.BLUE);
}
public void chartClick(View view) throws IOException{
String strData = "";
AssetManager amInput = context.getAssets();
BufferedReader reader;
InputStream is = null;
try {
is = amInput.open("Dinamap-Data.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
reader = new BufferedReader(new InputStreamReader(is));
try {
while( (strData = reader.readLine()) != null ) {
addBlock( strData ); //call to paint line
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//while loop
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//end mainClick() method for btnMain
public void writeClick(View view){
//write decimal data for wfs out to file from LinkedList<BinaryBlock>
//using WfsToString() method of BinaryBlock class in separate thread
(new Thread(new Runnable() {
#Override
public void run() {
FileOutputStream fos = null;
try {
fos = openFileOutput("wfs.txt", Context.MODE_WORLD_READABLE);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
ListIterator<BinaryBlockLite> itr = list.listIterator();
while (itr.hasNext()){
String temp = itr.next().WfsToString();
try {
fos.write(temp.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
})).start();
btnMain.setEnabled(false);
}
private void addBlock(final String strData) {
new Thread(new Runnable() {
public void run() {
int wfs[];
//read line into binaryBlockLite object and store object in Linked List
BinaryBlockLite bb = new BinaryBlockLite(strData);
list.add(bb);
//get the wfs data from the BinaryBlockLite object
wfs = new int[bb.getWfs().length];
wfs = bb.getWfs();
//grab each wfs individually and paint to the chart, and increment xTick
for (int k = 0; k < wfs.length; ++k){
/* check if we need to shift the x axis */
if (xTick > WaveFormRenderer.getXAxisMax()) {
WaveFormRenderer.setXAxisMax(xTick);
WaveFormRenderer.setXAxisMin(++lastMinX);
}
if (wfs[k] > 1000){
WFCurrentSeries.add(xTick, WFCurrentSeries.getY(xTick - 1));
}
else{
WFCurrentSeries.add(xTick, wfs[k]);
}
++xTick;
}
WFChartView.repaint();
}
}).start();
}
#Override
protected void onResume() {
super.onResume();
if (WFChartView == null) {
LinearLayout layout = (LinearLayout) findViewById(R.id.WFchart);
WFChartView = ChartFactory.getLineChartView(this, WFDataset, WaveFormRenderer);
layout.addView(WFChartView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// boolean enabled = WFDataset.getSeriesCount() > 0;
// setSeriesEnabled(enabled);
} else {
WFChartView.repaint();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
I think it's either super simple or a threading issue which is something that I haven't played with enough. Any help would be appreciated.
Looking at the code, I see that you add all the data to the series and then call repaint.
If you want the data to be gradually added, then move the repaint inside the for loop and put a Thread.sleep() inside, to give a chance to the UI thread to actually do the repaint.
I am planning to create a world clock widget in android. The clock should show the selected country's time as an analog clock widget. But I'm feeling difficulties as I'm a beginner in android.
My widget.xml file contains the following:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/Widget"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="8dip"
android:background="#drawable/myshape" >
<AnalogClock android:id="#+id/AnalogClock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:dial="#drawable/widgetdial"
android:hand_hour="#drawable/widgethour"
android:hand_minute="#drawable/widgetminute"/>
I am using the following configuration activity for my widget:-
(To display the city list)
package nEx.Software.Tutorials.Widgets.AnalogClock;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import android.app.Activity;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.os.Bundle;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AnalogClock;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RemoteViews;
import android.widget.TextView;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ConfigureApp extends Activity {
DateFormat df;
private ListView cityList;
public static String[][] citylist = new String[1242][10];
String[] cities = new String[1242];
String field[] = new String[20];
String list[][] = new String[1242][10];
String country = "";
String line = null;
int row = 0;
int col = 0;
// Variables for list view population
String city = "";
int position = 0;
public int[] listArray = new int[1242];
public static int len = 0;
public String[][] adapterCityList = new String[1242][3];
// Variables for passing intent data
public static final String citieslist = "com.world.citieslist";
AppWidgetManager awm;
Context c;
int awID;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Set the result to CANCELED. This will cause the widget host to cancel
// out of the widget placement if they press the back button.
setResult(RESULT_CANCELED);
try {
citylist = getCityList();
} catch (IOException e) {
Log.e("Loading CityList", e.getMessage());
}
for (int i = 0; i < 1242; i++) {
cities[i] = citylist[i][0];
}
// Set the view layout resource to use.
setContentView(R.layout.configure);
c = ConfigureApp.this;
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
awID = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
} else{
finish();
}
awm = AppWidgetManager.getInstance(c);
cityList=(ListView)findViewById(R.id.CityList);
// By using setAdpater method in listview we an add string array in list.
cityList.setAdapter(new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1, cities));
// cityList.setOnItemClickListener(cityListListener);
cityList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int pos, long id) {
df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String str = ((TextView) v).getText().toString();
RemoteViews remoteViews = new RemoteViews(c.getPackageName(),
R.layout.widget);
remoteViews.setTextViewText(R.id.mytext, str);
remoteViews.setTextViewText(R.id.date, df.format(new Date()));
Intent in = new Intent(c,clock.class);
PendingIntent pi = PendingIntent.getActivity(c, 0, in, 0);
remoteViews.setOnClickPendingIntent(R.id.Widget, pi);
awm.updateAppWidget(awID, remoteViews);
Intent result = new Intent();
result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,awID);
setResult(RESULT_OK, result);
finish();
}
});
}
private String[][] getCityList() throws IOException {
Context context = getApplicationContext();
InputStream instream = context.getResources().openRawResource(R.raw.cities_final);
// if file the available for reading
if (instream != null) {
// prepare the file for reading
InputStreamReader inputreader = new InputStreamReader(instream);
BufferedReader buffreader = new BufferedReader(inputreader);
while ((line = buffreader.readLine()) != null) {
field = line.split(",");
for (String x : field) {
list[row][col] = x;
col++;
if (x != null) {
country = x;
}
}
list[row][2] = country;
row++;
col = 0;
}
for (int i = 0; (i < list.length); i++) {
for (int j = 0; (j < 3); j++) {
if (j == 1) {
list[i][j] = list[i][j].substring(0, 6);
}
}
}
}
return list;
}
}
Can I use my own custom view in the widget, apart from analog clock? Or is there any other way to show the clock? like use the Imageview as the clock face and to draw the dial according to the time?
Please help me regarding this.!!!:(
A similar example for thermometer is given in this link
http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/
You can create your own view and make the clock as well.
You can replaced the clock dial, clock hand minute and clock hand hour with your own drawings. Then You'll have your own custom clock.
android:dial="#drawable/YOUR_OWN_DIAL"
android:hand_hour="#drawable/YOUR_OWN_HOUR"
android:hand_minute="#drawable/YOUR_OWN_MINUTE"
Test the layout in the Graphical Layout Tool to see how it look like.