I'm trying to load a text file from res/raw. I've looked at several code snippets and tried implementing a few ways but none seem to work for me. The code I currently am trying to get to work is this
TextView helloTxt = (TextView)findViewById(R.id.hellotxt);
helloTxt.setText(readTxt());
}
private String readTxt() {
InputStream inputStream = getResources().openRawResource(R.raw.hello);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i;
try {
i = inputStream.read();
while (i != -1) {
byteArrayOutputStream.write(i);
i = inputStream.read();
}
inputStream.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return byteArrayOutputStream.toString();
But it suffers from te same problem as all the others do.
a) (TextView)findViewById(R.id.hellotxt); says it depreciated and Eclipses recommends Migrating code.
b) getResources() isn't recognized and just suggests I add a method called getResources().
Initially I wanted to use assets folder but got the same error as b) but with getAssets().
This is a seperate class file I'm implementing this is called public class PassGen{} with one method at the moment called public String returnPass(){}
The functions getAssets and getResources should be called from a Context.
If you call it from within an Activity class it doesn't need a prefix, but otherwise you'd need to pass the context to the class that needs the functions and call e.g. context.getAssets().
Activity Class:
public class ReadFileActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Read read = new Read(getApplicationContext());
TextView helloTxt = (TextView) findViewById(R.id.hellotxt);
helloTxt.setText(read.readTxt());
}
}
Read Class:
public class Read {
Context ctx;
public Read(Context applicationContext) {
// TODO Auto-generated constructor stub
this.ctx = applicationContext;
}
public String readTxt() {
InputStream inputStream = ctx.getResources().openRawResource(R.raw.hello);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i;
try {
i = inputStream.read();
while (i != -1) {
byteArrayOutputStream.write(i);
i = inputStream.read();
}
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return byteArrayOutputStream.toString();
}
}
Related
I need to access a lot of images from the expansion file throughout a lot of activities.
Doing the:
expansionFile = APKExpansionSupport.getAPKExpansionZipFile(context, 8, -1);
fileStream = expansionFile.getInputStream("drawables/drawable-hdpi/" + image);
Drawable drawable = Drawable.createFromStream(fileStream, null);
for every activity is very slow, in some activities I need to load 4 ou more images at the same time.
So what do you think if I create a new class that abstracts this code in every activity?
So I created a class ExpansionFileRetriever, that retrieves the expansion file:
public class ExpansionFileRetriever{
private static ExpansionFileRetriever instance;
public static ExpansionFileRetriever get() {
if(instance == null) instance = getSync();
return instance;
}
private static synchronized ExpansionFileRetriever getSync() {
if(instance == null) instance = new ExpansionFileRetriever();
return instance;
}
public ExpansionFileRetriever(){
// here you can directly access the Application context calling
Context c = App.get();
try {
expansionFile = APKExpansionSupport.getAPKExpansionZipFile(c, 20, -1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ZipResourceFile expansionFile;
public Drawable getDrawable(String path, String resource) {
InputStream fileStream = null;
String file = path + resource;
try {
fileStream = expansionFile.getInputStream(file);
Drawable drawable = Drawable.createFromStream(fileStream, null);
return drawable;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
and whenever I need to access files for the expansion file
I just use
ExpansionFileRetriever expFile = ExpansionFileRetriever.get();
and to get, say a Drawable all I do is:
expFile.getDrawable(path, name)
The first time my app runs it creates a database in which it loads 6,000 rows from a file in /res/raw. I can't do this asynchronously as the app depends on it entirely. It runs rapidly on my phone - a Moto X - but it's really slow in all my emulators and I'm concerned it could be a bit slower on slower devices thus making the user stare at a blank screen for a few seconds before the app does anything.
Is there a way to put a progress bar while running the overrided SQLiteOpenHelper's onCreate() methood and have it update the progress bar with how far along it is, with a message saying something like "Initializing data for first use!"?
I solved this problem by starting an AsyncTask in onCreate and then only loading the layout at the end of the 'AsyncTask` (or if the data had previously been loaded). It works beautifully as a loading screen. I followed this tutorial http://www.41post.com/4588/programming/android-coding-a-loading-screen-part-1 (which explains the details more) then changed it a bit for my needs (such as loading a raw resource).
I should say that although it does it asynchronously because the main layout hasn't loaded the user has to wait for the loading to complete before he or she can continue, so hopefully that means it doing it asynchronously won't be a problem for you with the app depending on the database.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE);
dataAddedToDB = (sharedPref.getBoolean(PXS_RXS_UPDATE, false));
if (!dataAddedToDB) {
new LoadViewTask(this).execute();
} else {
setContentView(R.layout.activity_main);
}
}
In the AsyncTask it loads the database showing how far it has got and showing your message and then only goes on to show the layout at the end. (BTW, it is helpful to lock the screen orientation while doing this to stop it messing it up).
EDIT: publishProgress(counter); passes the value of where the task has got to to onProgressUpdate().
private class LoadViewTask extends AsyncTask<Void, Integer, Void> {
private Context context;
public LoadViewTask(Context context) {
this.context = context.getApplicationContext();
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setTitle("Loading...");
progressDialog.setMessage("Initializing data for first use!");
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(false);
// this counts how many line to be added to the database so it can later tell how far it has got.
final Resources resources2 = context.getResources();
InputStream inputStream2 = resources2.openRawResource(R.raw.rawherbaldata);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream2));
int lineCount = 0;
try {
String line;
while ((line = reader.readLine()) != null) {
lineCount++;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
progressDialog.setMax(lineCount);
progressDialog.setProgress(0);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
HerbalDatabaseOpenHelper mHerbalDbHelper = new HerbalDatabaseOpenHelper(MainActivity.this);
SQLiteDatabase db = mHerbalDbHelper.getWritableDatabase();
int counter = 0;
final Resources resources2 = context.getResources();
InputStream inputStream2 = resources2.openRawResource(R.raw.rawherbaldata);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream2));
db.beginTransaction();
try {
int lineNumber = 1;
String line;
while ((line = reader.readLine()) != null) {
// CODE FOR ENTERING LINE INTO DATABASE
// EDIT: the following keeps the task updated on where it has got to, passing the count to onProgressUpdate()
counter++;
publishProgress(counter);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
db.setTransactionSuccessful();
db.endTransaction();
db.close();
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE);
pxsRxsUpdate = true;
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean(PXS_RXS_UPDATE, pxsRxsUpdate);
editor.commit();
// initialize the View
setContentView(R.layout.activity_main);
}
}
You could use another intermediate activity which would show the progress dialog and then send you back to the main activity when done.
First you'll need a static method that a boolean if the DB has already been create.
Then inside of your activity's onCreate call the middleman if necessary:
DbHelper mDbHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!DbHelper.isDbCreated()) {
Intent intent = new Intent(this, DbActivity.class);
startActivity(intent);
finish();
return;
}
// Do normal stuff like instantiating the helper and so on
mDbHelper = new DbHelper();
...
}
Then inside of this "middleman" activity show the ProgressDialog and create the database.
Once you're done, hide the dialog and go back to your main activity:
mProgress.dismiss();
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
return;
If your static method isDbCreated() is created properly, you won't reveal the MainActivity's content until the database is created.
EDIT:
Here's the method I use to check for the database. Perhaps it will help you.
public boolean isDbCreated() {
String sDatabasePath = context.getDatabasePath(DB_NAME).getPath();
SQLiteDatabase tmpDb = null;
if (mContext.getDatabasePath(DB_NAME).exists()) {
try {
tmpDb = SQLiteDatabase.openDatabase(sDatabasePath, null,
SQLiteDatabase.OPEN_READONLY);
tmpDb.close();
} catch (SQLiteException e) {
e.printStackTrace();
}
} else {
Log.e(TAG, "DB file doesn't exist.");
// If the parent dir doesn't exist, create it
File parentDir = new File(mContext.getDatabasePath(DB_NAME).getParent());
if (!parentDir.exists()) {
if (parentDir.mkdirs()) {
Log.d(TAG, "Successfully created the parent dir:" + parentDir.getName());
} else {
Log.e(TAG, "Failed to create the parent dir:" + parentDir.getName());
}
}
}
return (tmpDb != null);
}
This code is able to make the android device as a USB host for the hardware model. It also can read data from the hardware correctly in Main Activity. However, as soon as I moved it to another activity, everything still works but the data reading is incorrect.
For instance, I'm trying to write the data read into file. First activity is to input filename and just a button to send to another activity. The code below is in the second activity
public class Temp extends Activity {
private FileOutputStream outputStream;
public static D2xxManager ftD2xx= null;
Handler mHandler = new Handler();
FT_Device ftDev = null;
int devCount = 0;
UsbDevice device = null;
TextView Text =null;
String temp = null;
_4DPoint P = null;
int rd = 0;
byte[] byt = null;
byte[] Fdata = null;
String outp = "";
String From_Serial = "";
int Min = -1;
String fileName;
Context c;
final Runnable updateResults = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Text.setText("" + Min + '\n' + temp);
}
};
public void getData(){
try {
outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
byt = new byte[256];//{(byte)'a','b','c','d',};
Toast.makeText(getBaseContext(), "start " + fileName , Toast.LENGTH_LONG).show();
Text = (TextView)findViewById(R.id.test2);
device = (UsbDevice) getIntent().getParcelableExtra("USB");
ftD2xx = D2xxManager.getInstance(c);
ftD2xx.addUsbDevice(device);
devCount = ftD2xx.createDeviceInfoList(c);
if (devCount > 0) {
ftDev = ftD2xx.openByUsbDevice(c, device);
}
if( ftDev.isOpen() == true ) {
ftDev.setBitMode((byte)0 , D2xxManager.FT_BITMODE_RESET);
ftDev.setBaudRate(38400);
ftDev.setDataCharacteristics(D2xxManager.FT_DATA_BITS_8, D2xxManager.FT_STOP_BITS_1, D2xxManager.FT_PARITY_NONE);
ftDev.setFlowControl(D2xxManager.FT_FLOW_NONE, (byte) 0x0b, (byte) 0x0d);
Thread t = new Thread() {
public void run() {
int i;
while(true){
rd=0;
while (rd==0){
rd = ftDev.read(byt, 14);
}
for(i=0; i<rd; i++)
outp += (char)byt[i];
From_Serial = new String(outp);
P = new _4DPoint(From_Serial);
temp = String.format("%s: %f %f %f %f %d\n", From_Serial, P.R, P.G, P.B, P.L, P.camera);
try {
outputStream.write(temp.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outp = "";
mHandler.post(updateResults);
}
}
};
t.start();
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (D2xxException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_color);
// Show the Up button in the action bar.
setupActionBar();
Intent intent = getIntent();
fileName = intent.getStringExtra("File Name");
c = this;
getData();
}
The set up should be fine since it's reading data from hardware, but the data read is incorrect.
Also, I'm wondering why we need to create new thread while reading data. I tried not creating new thread and it didn't work well, but still have no idea why? I tried to contact the person who wrote the code to read data but no reply.
Any help would be really appreciated :)
You state that you receive data, therefor I think you should look at your ftDev settings. Try for example to set ftDev.setBaudRate(115200) (this worked for me) or try playing with your other ftDev Settings a little bit.
The settings I use in my programm are:
int baudRate = 115200;
byte stopBit = 1; /*1:1stop bits, 2:2 stop bits*/
byte dataBit = 8; /*8:8bit, 7: 7bit*/
byte parity = 0; /* 0: none, 1: odd, 2: even, 3: mark, 4: space*/
byte flowControl = 1; /*0:none, 1: flow control(CTS,RTS)*/
If this won't work, it is wise to first check this data communication with a computer program e.g. or to analyse the incomming 'wrong' data.
I'm creating an app wich is supposed to do the following:
- When started shows a splash/info-activity.
- In next activity shows a list of names as checkboxes
- user can add new names via EditText & Add-button (list updated dynamically)
- When closing app, and reopening, names previously added should be saved and displayed in list.
I've tried to setup my list as ArrayList in my startingactivity just to see if I can save and load my information correctly:
public class StartActivity extends Activity implements OnClickListener {
Typeface face;
TextView tvStartIntrotext;
Button bStartStart;
ArrayList<String> names = new ArrayList<String>();
String NAMESFILE = "names_file";
FileOutputStream fos;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.startactivity);
face = Typeface.createFromAsset(getAssets(), "andalemono.ttf");
bStartStart = (Button) findViewById(R.id.bStartStart);
bStartStart.setTypeface(face);
tvStartIntrotext = (TextView) findViewById(R.id.tvStartIntrotext);
tvStartIntrotext.setTypeface(face);
bStartStart.setOnClickListener(this);
try {
fos = openFileOutput(NAMESFILE, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
names.add("Name Name");
oos.writeObject(names);
oos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.startactivity, menu);
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent startIntent = new Intent(StartActivity.this, Choose.class);
startActivity(startIntent);
}
}
To read and display I have this in my other activity so far:
public class Choose extends Activity implements OnClickListener {
String NAMESFILE = "names_file";
FileInputStream fis;
Button bChooseChoose, bChooseAdd;
Typeface face;
TextView tvChoosePick;
EditText etChooseAddnew;
LinearLayout llMain;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.slideinright, R.anim.slideoutleft);
setContentView(R.layout.choose);
face = Typeface.createFromAsset(getAssets(), "andalemono.ttf");
bChooseChoose = (Button) findViewById(R.id.bChooseChoose);
bChooseChoose.setTypeface(face);
bChooseChoose.setOnClickListener(this);
bChooseAdd = (Button) findViewById(R.id.bChooseAdd);
bChooseAdd.setTypeface(face);
bChooseAdd.setOnClickListener(this);
tvChoosePick = (TextView) findViewById(R.id.tvChoosePick);
tvChoosePick.setTypeface(face);
etChooseAddnew = (EditText) findViewById(R.id.etChooseAddnew);
etChooseAddnew.setTypeface(face);
etChooseAddnew.setBackgroundResource(R.color.white1);
etChooseAddnew.setHintTextColor(color.greytext);
llMain = (LinearLayout) findViewById(R.id.llMain);
try {
fis = openFileInput(NAMESFILE);
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<Object> names = (ArrayList<Object>) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < names.size(); i++) {
CheckBox cbb = new CheckBox(this);
cbb.setText(names.get(i));
cbb.setTypeface(face);
cbb.setTextSize(16);
llMain.addView(cbb);
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()){
case R.id.bChooseChoose:
break;
case R.id.bChooseAdd:
/*This button for adding new list name*/
break;
}
}
}
One error I'm getting at this point is "setText" in my for-loop. Don't yet know how to get the information from the file opened to display in a list correctly. Although the for-loop works when no fileInput/Output is used.
Any pointers to what I can try would be really helpful, since I'm new to Android programming. :)
Thx!
The problem is that names variable declared inside try-catch block and cannot be accessed from outside. Just move declaration out of the block:
List<Object> names;
try {
fis = openFileInput(NAMESFILE);
ObjectInputStream ois = new ObjectInputStream(fis);
names = (ArrayList<Object>) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
names = Collections.emptyList();
}
UPDATE
And you can't use cbb.setText(names.get(i)) because names.get(i) is not a String. It's an object (that actually should be String if you saved strings in NAMESFILE).
You can either case it to String:
cbb.setText((String)names.get(i))
or use toString method:
cbb.setText(names.get(i).toString())
I was trying to do some data loading in Splash page in my app using asynctask, but the app stuck at the splash screen, and logcat print:
Default buffer size used in BufferedOutputStream constructor. It would be better to be explicit if an 8k buffer is required.
Here are my code
package com.appkon.hdtvs;
public class Splash extends Activity {
private ChannelDB mDB;
private TextView loading;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
AppConnect.getInstance(this);
loading =(TextView)findViewById(R.id.loading);
}
private class SetDB extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
try {
if (tabIsExist(null)==true){
mDB.Reset();
Bitmap bigbang1 = BitmapFactory.decodeResource(getResources(), R.drawable.bigbang1);
Bitmap bigbang2 = BitmapFactory.decodeResource(getResources(), R.drawable.bigbang2);
mDB.createchannelEntry(new ChannelPoster(castle4, "灵书妙探 (第四季)" ,"http://appkon.com/hdtvs/channel/castle4.xml" ,"http://movie.douban.com/subject/6742616/" ));
mDB.createchannelEntry(new ChannelPoster(castle3, "灵书妙探 (第三季)" ,"http://appkon.com/hdtvs/channel/castle4.xml" ,"http://movie.douban.com/subject/4836898/" ));
}
}catch (Exception e) {
Intent i = new Intent();
i.setClassName("com.appkon.hdtvs",
"com.appkon.hdtvs.HDtvs");
finish();
startActivity(i);
}
return null;
}
protected void onProgress(String load) {
loading.setText("载入中···");
}
protected void onPostExecute(String finish) {
loading.setText("载入完成");
}
}
public boolean tabIsExist(String channelS_TABLE){
boolean result = false;
if(channelS_TABLE == null){
return false;
}
Cursor cursor= ChannelDB.check();
startManagingCursor(cursor);
try {
if(cursor.moveToNext()){
int count = cursor.getInt(0);
if(count>0){
result = true;
}
}
} catch (Exception e) {
Log.e(this.toString(),"error:"+e.toString());
Intent intent = new Intent(this,HDtvs.class);
startActivity(intent);
this.finish();
}
return result;
}
}
So what seem to be the problem? Is that because my res images are too big.
Somewhere a BufferedOutputStream is used but not constructed with a size (second argument). Maybe you used libs do the mess.