Java.lang.NullPointerException when trying to declare a Spinner - android

public void directionSpinner (String directions []) {
//Does some stuff to assign namedDirections [0] and namedDirections[1] a value.
dirSpinner = (Spinner) findViewById(R.id.route_direction_spinner); //THIS IS LINE 87
dirSpinner.setOnItemSelectedListener(this);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add(namedDirections[0]);
adapter.add(namedDirections[1]);
dirSpinner.setAdapter(adapter);
Log.i(TAG, "spinner populated");
}
LogCat:
12-09 20:50:13.497: E/AndroidRuntime(857): FATAL EXCEPTION: main
12-09 20:50:13.497: E/AndroidRuntime(857): java.lang.NullPointerException
12-09 20:50:13.497: E/AndroidRuntime(857): at android.app.Activity.findViewById(Activity.java:1839)
12-09 20:50:13.497: E/AndroidRuntime(857): at com.nicotera.colton.londontransitguide.RoutesActivity.directionSpinner(RoutesActivity.java:87)
12-09 20:50:13.497: E/AndroidRuntime(857): at com.nicotera.colton.londontransitguide.MyInnerClass.onPostExecute(RoutesActivity.java:142)
12-09 20:50:13.497: E/AndroidRuntime(857): at com.nicotera.colton.londontransitguide.MyInnerClass.onPostExecute(RoutesActivity.java:1)
Anyways, route_direction_spinner is defined correctly. directionSpinner() runs after an AsyncTask is completed.
Entire Code:
package com.nicotera.colton.londontransitguide;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jsoup.*;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
public class RoutesActivity extends Activity implements OnItemSelectedListener {
Spinner dirSpinner;
Spinner routeSpinner;
static String [] namedDirections = new String [2];
private static final String TAG = "RoutesActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_routes);
dirSpinner = (Spinner) findViewById(R.id.route_direction_spinner); // Create an ArrayAdapter using the string array and a default spinner layout
routeSpinner = (Spinner) findViewById(R.id.route_name_spinner); // Create an ArrayAdapter using the string array and a default spinner layout
routeSpinner.setOnItemSelectedListener(this);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.routes_array, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Apply the adapter to the spinner
routeSpinner.setAdapter(adapter);
Log.i(TAG, "second spinner populated");
}
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
Log.i(TAG, "Item selected");
//DecimalFormat df = new DecimalFormat("00##");
int tempPos = pos;
Log.i(TAG, ("Position of selected item: " + tempPos));
int routeSelected;
if (tempPos < 17)
routeSelected = (tempPos + 1);
else if (tempPos >= 17 && tempPos < 29)
routeSelected = (tempPos + 2);
else
routeSelected = (tempPos + 3);
String temp;
if (routeSelected < 10)
temp = ("0") + routeSelected;
else
temp = ("") + routeSelected;
String url = "http://www.ltconline.ca/WebWatch/MobileAda.aspx?r=" + temp;
new MyInnerClass().execute(url);
}
public void directionSpinner (String directions []) {
int temp;
for (int i = 1; i <=2; i++)
{
temp = Integer.parseInt(directions[i]);
if (temp == 1)
namedDirections[(i-1)] = "Eastbound";
else if (temp == 2)
namedDirections[(i-1)] = "Northbound";
else if (temp == 3)
namedDirections[(i-1)] = "Southbound";
else if (temp == 4)
namedDirections[(i-1)] = "Westbound";
}
//setContentView(R.layout.activity_routes);
dirSpinner.setOnItemSelectedListener(this);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add(namedDirections[0]);
adapter.add(namedDirections[1]);
dirSpinner.setAdapter(adapter);
Log.i(TAG, "spinner populated");
}
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
}
class MyInnerClass extends AsyncTask<String, Void, String> {
String [] directions = new String [3];
String [] directionNames = new String [3];
private static final String TAG = "RoutesActivity";
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
RoutesActivity tc = new RoutesActivity();
tc.directionSpinner(directions);
}
#Override
protected String doInBackground(String... params) {
try{
Pattern routeDirPattern = Pattern.compile("\\&d=(\\d{1,2})");
Connection conn = Jsoup.connect(params[0]);
Document doc = conn.get();
int i = 0;
Elements routeLinks = doc.select("a[href]");
for (Element routeLink : routeLinks) {
i = (i + 1);
String name = routeLink.text();
Attributes attrs = routeLink.attributes();
String href = attrs.get("href");
Matcher m = routeDirPattern.matcher(href);
if (m.find()) {
String number = m.group(1);
directions [i] = number;
directionNames [i] = name;
Log.i(TAG, directionNames [i]);
}
}
}catch(Exception e){Log.d("doinbackground exception", e.toString());}
return ("Done");
}
}
Basically, this grabs some values from a transit website. This section of code so far just gets the direction of the route based off the route selected.

(Your directionSpinner() method is different in the two snippets you've posted, and I'm working using the one added later, but this solution should work for both snippets, assuming the problem is the same)
Your problem is that you're not following the Activity lifecycle properly.
When you call:
RoutesActivity tc = new RoutesActivity();
tc.directionSpinner(directions);
You are actually creating a brand new instance of RoutesActivity. And since you're calling it as a standard Java class, it never follows the Activity lifecycle, which means that onCreate() is never called, which in turn means that your two spinner objects remain null (as you assign values to them in onCreate()).
Due to this, when you use:
dirSpinner.setOnItemSelectedListener(this);
dirSpinner is actually null resulting in a NullPointerException.
Instead, try using:
RoutesActivity.this.directionSpinner(directions);
Instead of:
RoutesActivity tc = new RoutesActivity();
tc.directionSpinner(directions);

Related

How to read TensorBuffer

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()

Storing seriaized ArrayList in SharedPreferences - ArrayList is empty when retrieving

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.

Android Spinner reselects itself to first value every half second

So, I have a spinner, populated with ~35 values. If I select, say, the fifth item, then when it is selected, it does what it is supposed to do (populate a second spinner). My problem is that shortly afterwards (<1/2 second) it reverts the values in the second spinner to what they would be if option 1 in the first spinner were selected. The fifth item in the first spinner is still selected but it acts as though the first item gets selected twice per second.
I've tried everything I could find on this (barely anything) and nothing has worked so far. This basically has me stuck on going further in my app.
Entire Code:
package com.nicotera.colton.londontransitguide;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jsoup.*;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
public class RoutesActivity extends Activity implements OnItemSelectedListener {
Spinner dirSpinner;
Spinner routeSpinner;
static String [] namedDirections = new String [2];
private static final String TAG = "RoutesActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_routes);
dirSpinner = (Spinner) findViewById(R.id.route_direction_spinner); // Create an ArrayAdapter using the string array and a default spinner layout
routeSpinner = (Spinner) findViewById(R.id.route_name_spinner); // Create an ArrayAdapter using the string array and a default spinner layout
routeSpinner.setOnItemSelectedListener(this);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.routes_array, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Apply the adapter to the spinner
routeSpinner.setAdapter(adapter);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
Log.i(TAG, "Item selected");
//DecimalFormat df = new DecimalFormat("00##");
int tempPos = pos;
Log.i(TAG, ("Position of selected item: " + tempPos));
int routeSelected;
if (tempPos < 17)
routeSelected = (tempPos + 1);
else if (tempPos >= 17 && tempPos < 29)
routeSelected = (tempPos + 2);
else
routeSelected = (tempPos + 3);
String temp;
if (routeSelected < 10)
temp = ("0") + routeSelected;
else
temp = ("") + routeSelected;
String url = "http://www.ltconline.ca/WebWatch/MobileAda.aspx?r=" + temp;
new MyInnerClass().execute(url);
}
public void directionSpinner (String directions []) {
int temp;
for (int i = 1; i <=2; i++)
{
temp = Integer.parseInt(directions[i]);
if (temp == 1)
namedDirections[(i-1)] = "Eastbound";
else if (temp == 2)
namedDirections[(i-1)] = "Northbound";
else if (temp == 3)
namedDirections[(i-1)] = "Southbound";
else if (temp == 4)
namedDirections[(i-1)] = "Westbound";
}
//setContentView(R.layout.activity_routes);
dirSpinner.setOnItemSelectedListener(this);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add(namedDirections[0]);
adapter.add(namedDirections[1]);
dirSpinner.setAdapter(adapter);
Log.i(TAG, "spinner populated");
}
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
class MyInnerClass extends AsyncTask<String, Void, String> {
String [] directions = new String [3];
String [] directionNames = new String [3];
private static final String TAG = "RoutesActivity";
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
RoutesActivity.this.directionSpinner(directions);
}
#Override
protected String doInBackground(String... params) {
try{
Pattern routeDirPattern = Pattern.compile("\\&d=(\\d{1,2})");
Connection conn = Jsoup.connect(params[0]);
Document doc = conn.get();
int i = 0;
Elements routeLinks = doc.select("a[href]");
for (Element routeLink : routeLinks) {
i = (i + 1);
String name = routeLink.text();
Attributes attrs = routeLink.attributes();
String href = attrs.get("href");
Matcher m = routeDirPattern.matcher(href);
if (m.find()) {
String number = m.group(1);
directions [i] = number;
directionNames [i] = name;
Log.i(TAG, directionNames [i]);
}
}
}catch(Exception e){Log.d("doinbackground exception", e.toString());}
return ("Done");
}
}
}
I was using the same onselected listener for both without an if statement to check which one was clicked so it just thought that the first one was clicked.
This is the corrected code:
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
Spinner spnr = (Spinner) parent;
Log.i(TAG, "Item selected");
switch(parent.getId()) {
case R.id.route_name_spinner:
//DecimalFormat df = new DecimalFormat("00##");
int tempPos = pos;
Log.i(TAG, ("Position of selected item: " + tempPos));
int routeSelected;
if (tempPos < 17)
routeSelected = (tempPos + 1);
else if (tempPos >= 17 && tempPos < 29)
routeSelected = (tempPos + 2);
else
routeSelected = (tempPos + 3);
String temp;
if (routeSelected < 10)
temp = ("0") + routeSelected;
else
temp = ("") + routeSelected;
String url = "http://www.ltconline.ca/WebWatch/MobileAda.aspx?r=" + temp;
new MyInnerClass().execute(url);
case R.id.route_direction_spinner:
}
}

Android-World Clock Widget analog

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.

How to use getPackageManager?

In order to show installed applications on the Android emulator, I tried this code. It compiles successfully but doesn't work. What's wrong?
package pack.GetAllInstalledApplications;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.pm.PackageInfo;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class GetAllInstalledApplicationsExample extends Activity {
public ArrayList <PackageInfoStruct> res = new ArrayList <PackageInfoStruct>();
public ListView list;
public String app_labels[];
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getPackages();
list = (ListView)findViewById(R.id.ListView01);
try{
list.setAdapter(new ArrayAdapter<String> (this,android.R.layout.simple_dropdown_item_1line,app_labels));
}catch(Exception e){
System.out.println("Err ++> " + e.getMessage());
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
private ArrayList
<PackageInfoStruct> getPackages() {
ArrayList
<PackageInfoStruct> apps = getInstalledApps(false);
final int max = apps.size();
for (int i=0; i < max; i++) {
apps.get(i);
}
return apps;
}
private ArrayList
<PackageInfoStruct> getInstalledApps(boolean getSysPackages) {
List
<PackageInfo> packs = getPackageManager().getInstalledPackages(0);
try{
app_labels = new String[packs.size()];
}catch(Exception e){
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
for(int i=0;i < packs.size();i++) {
PackageInfo p = packs.get(i);
if ((!getSysPackages) && (p.versionName == null)) {
continue ;
}
PackageInfoStruct newInfo = new PackageInfoStruct();
newInfo.appname = p.applicationInfo.loadLabel(getPackageManager()).toString();
newInfo.pname = p.packageName;
newInfo.versionName = p.versionName;
newInfo.versionCode = p.versionCode;
newInfo.icon = p.applicationInfo.loadIcon(getPackageManager());
res.add(newInfo);
app_labels[i] = newInfo.appname;
}
return res;
}
}
class PackageInfoStruct {
String appname = "";
String pname = "";
String versionName = "";
int versionCode = 0;
Drawable icon;
}
In your call to list.setAdapter you should probably use a different layout. I tried simple_list_item_1
list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, app_labels));
and it appears to then display the items correctly.
Before rendering the app labels you should add some log in order to understand if you are actually retrieving the apps. Verified that then you can deal with the adapter.
Remember that the ArrayAdapter's constructor get as second parameter the resource id of a text view (otherwise it crashes), so make sure of that.
Moreover, for discarding the system package I use this line of code:
...
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) continue;
...
where pi is the PackageInfo.
Let me know if it works
I change the adapter layout, use the android.R.layout.simple_list_item_1 on your code, and it works.

Categories

Resources