As a newbie to Android programming, I have attached four files to the assets folder of my library.
You can see the attached image.
I want to access these files through the Android library using the below code (if I don't use this code in Android library, it runs without an error when I use it in MainActivity).
public void copy_weights() {
try {
AssetManager assetFiles = getAssets();
String[] files = assetFiles.list("");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace(); //catch the error in this line
} catch (Exception e) {
e.printStackTrace();
}
}
but this code give me the error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.AssetManager android.Context.getAssets' on a null object refrence
I tried other methods like direct accessing via home:///android_asset/7.cfg but it can't access the files too.
EDIT 1
I call the copy_weights() in mainActivity like below
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
final new_class newClass=new new_class();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button =(Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
TextView textView=(TextView) findViewById(R.id.textView);
newClass.copy_weights();
}
});
}
EDIT 2
new_class code
package com.example.mylittlelibrary;
import android.content.res.AssetManager;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.dnn.Net;
import org.opencv.imgcodecs.Imgcodecs;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.File;
public class new_class extends AppCompatActivity {
private boolean opencv_sucessfully_included;
private static int BUFFER_SIZE = 1024;
public new_class() { }
private static void copyAssetFiles(InputStream in, OutputStream out) {
try {
byte[] buffer = new byte[BUFFER_SIZE];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public void copy_weights() {
try {
AssetManager assetFiles = getAssets();
// MyHtmlFiles is the name of folder from inside our assets folder
String[] files = assetFiles.list("");
// Initialize streams
InputStream in = null;
OutputStream out = null;
for (int i = 0; i < files.length; i++) {
File file = new File(Environment.getExternalStorageDirectory() + "/" + files[i]);
if (!file.exists()) {
in = assetFiles.open(files[i]);
out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/" + files[i]);
copyAssetFiles(in, out);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
You can't initialize an Activity like that. If you need a reference to a Context (such as with getAssets()) you should pass it to the class.
First, remove your AppCompatActivity extension:
public class new_class {
Then change your constructor and add a global variable:
private Context context;
public new_class(Context context) {
this.context = context;
}
You'll notice some of your methods are now in red and unresolved. Just add context. before them. For example
context.getAssets()
Make a new instance of that class by adding a this argument to it:
final new_class newClass = new new_class(this);
Also, you shouldn't put anything before super.onCreate() is called, so move that to go after it.
Related
Im creating a weight tracking app where the user inputs their weight clicks a save button and then the weight is saved. There is also a load button that loads all the previous inputs. The problem I'am having is that once load is clicked it does load up the weights on the screen but it does it all in one line other than a separate line for each.
I have checked the text file and all the weights are stored in a line each so there's no problem in the function that stores the inputs.
Here is the code for the `weight tracker
package com.example.workouttracker;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class WeightTracking extends AppCompatActivity {
private static final String FILE_NAME = "WeightTracking.txt";
EditText mEditText;
EditText mEditText2;
private Button button_back_home;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_weight_tracking);
mEditText = findViewById(R.id.weight);
mEditText2 = findViewById(R.id.weight2);
button_back_home=(Button) findViewById(R.id.button_back_home);
button_back_home.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
homePage();
}
private void homePage(){
startActivity(new Intent(getApplicationContext(),MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
});
}
public void save(View v) {
String text = mEditText.getText().toString();
FileOutputStream fos = null;
try {
fos = openFileOutput(FILE_NAME, MODE_APPEND);
fos.write((text + "kg's\n").getBytes());
mEditText.getText().clear();
Toast.makeText(this, "Saved to " + getFilesDir() + "/" + FILE_NAME,
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void load(View v) {
FileInputStream fis = null;
try {
fis = openFileInput(FILE_NAME);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String text;
while ((text = br.readLine()) != null) {
sb.append(text);
sb.append('\n');
}
mEditText2.setText(sb.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Someone know's how to get it to load each weight line by line?
Thanks
`
can you please check your xml file, if you have added property android:inputType="textMultiLine" on the edittext
Try changing your code like this:
String sb = "";
String text;
while ((text = br.readLine()) != null) {
sb = sb + text + "\n";
}
I have a program that establishes a Bluetooth connection, reads the InputStream to a textView, and can disconnect from the module. While I can successfully disconnect and reconnect to the module (HC-05) as many times as I please, I can't get an InputStream read anymore after I reconnect. I believe it is because I don't know how to reinitialize the thread I'm using to read the InputStream. I am very new to java and android programming, any help with this issue would be appreciated.This is my code:
The textView for the read display is called 'Status' and I am hoping to "reset" the thread upon the onclick connect().
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
public class MainActivity extends AppCompatActivity implements Runnable {
private BluetoothAdapter adapter;
private InputStream inputStream;
private OutputStream outputStream;
private Thread thread;
private TextView Status;
private TextView Connection;
private BluetoothSocket socket = null;
private boolean threadStatusInitial=true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Status=(TextView) findViewById(R.id.StatusID);
Connection=(TextView) findViewById(R.id.ConnectionStatus);
adapter= BluetoothAdapter.getDefaultAdapter();
if(adapter==null){
Toast.makeText(this,"bluetooth is unavailable",Toast.LENGTH_SHORT).show();
finish();
return;
}
thread=new Thread(this);
}
public void connect(View view){
Set<BluetoothDevice> devices=adapter.getBondedDevices();
for(BluetoothDevice device:devices){
if(device.getName().startsWith("HC-05")){
try {
socket=device.createRfcommSocketToServiceRecord(device.getUuids()[0].getUuid());
socket.connect();
Connection.setText("Connected");
inputStream=socket.getInputStream();
outputStream=socket.getOutputStream();
if (threadStatusInitial){
thread.start();
threadStatusInitial=false; //this ensures that the thread.start() method will only be called during the first connection
}
} catch (IOException e) {
Toast.makeText(this,"Can't Connect",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
break;
}
}
}
public void Disconnect(View view) throws InterruptedException {
if (inputStream != null) {
try {inputStream.close();} catch (Exception e) {}
inputStream = null;
}
if (outputStream != null) {
try {outputStream.close();} catch (Exception e) {}
outputStream = null;
}
if (socket != null) {
try {socket.close();} catch (Exception e) {Toast.makeText(this,"Can't Connect",Toast.LENGTH_LONG).show();}
socket = null;
}
Connection.setText("Disconnected");
}
#Override
public void run() {
String textInput = "hi";
byte[] writeBytes=textInput.getBytes();
if(outputStream!=null){
try {
outputStream.write(writeBytes);
} catch (IOException e) {
Toast.makeText(this,"Unable to Write to Bluetooth ",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
while(inputStream!=null){
byte [] buffer=new byte[2048];
try {
int length=inputStream.read(buffer);
final String strReceived = new String(buffer, 0, length);
runOnUiThread(new Runnable(){
#Override
public void run() {
Status.setText(strReceived);
}});
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ProgressDialog cannot show when i add progressDialog.dismiss() method on my code
I also try to add Thread.sleep() so that it execution will sleep for some time which can show progressdialog for some time but this will also not work.
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.ResolveInfo;
import android.os.Environment;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
public class Extraction {
ProgressDialog progressDialog;
public Extraction(List<ResolveInfo> apps, String publicSourceDir, String apkname, Context context) {
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Extracting");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setIndeterminate(true);
progressDialog.show();
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
File file = new File(publicSourceDir);
File file1 = new File(Environment.getExternalStorageDirectory().toString() + "/Extracted APK");
if (!file1.exists())
file1.mkdirs();
file1 = new File(file1.getPath() + "/" + apkname + ".apk");
if (!file1.exists())
file1.createNewFile();
bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file1));
byte[] buf = new byte[1024];
int len;
while ((len = bufferedInputStream.read(buf)) > 0) {
bufferedOutputStream.write(buf, 0, len);
}
Thread.sleep(1000);
progressDialog.dismiss();
Toast.makeText(context, "Apk Extracted", Toast.LENGTH_LONG).show();
bufferedInputStream.close();
bufferedOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
bufferedInputStream.close();
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
your need to put your long running work in a separate Thread or asyncTask
Because the UI is only updated at the end when your long running code is completed and then the show/dismiss is already called. thats why you only see the final result: a dismissed dialog
see the example (quoted from here:
Android: ProgressDialog doesn't show ):
Do something like:
public void doBackup(View view) throws IOException{
final ProgressDialog pd = new ProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("Running backup. Do not unplug drive");
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
Thread mThread = new Thread() {
#Override
public void run() {
File source = new File("/mnt/extSdCard/DirectEnquiries");
File dest = new File("/mnt/UsbDriveA/Backup");
copyDirectory(source, dest);
pd.dismiss();
}
};
mThread.start();
}
and also here:
ProgressDialog not showing while performing a task
how can I read a text file which I got from uri (size is about 2Mb) in a special way without turning the screen black for a minute and then displaying the whole string ? My problem is that I set the textView text to whole string and that's why it lags. Is there any way to make it read it in small parts and then display them in small parts ? In a way that ES file explorer does.
Here is my actual, not very efficient and lagging code:
InputStream inputStream = null;
String str = "";
StringBuffer buf = new StringBuffer();
TextView txt = (TextView)findViewById(R.id.textView);
try {
inputStream = getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
if (inputStream!=null) {
try {
while ((str = reader.readLine()) != null) {
buf.append(str + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
txt.setText(buf.toString());
}
My first idea would be as follows:
txt.setText("");
if (inputStream!=null) {
try {
while ((str = reader.readLine()) != null) {
txt.append(str + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Consider using a loader.
Loaders are running on a different thread and therefore do not block the UIThread which creates your interface. Because you are loading a lot of data into memory, the system has to wait until it can display your interface. This causes the black screen. The problem can even force the system to shut down your app because it is doing to much work on it's main thread.
http://www.androiddesignpatterns.com/2012/07/loaders-and-loadermanager-background.html
There are different type of loaders.
You may need an AsyncTaskLoader or if you are querying a content provider a CursorLoader.
Update1:
package de.xyaren.fileloader;
import android.app.LoaderManager;
import android.content.AsyncTaskLoader;
import android.content.Loader;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class MainActivity extends ActionBarActivity implements LoaderManager.LoaderCallbacks<String> {
private TextView txt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView) findViewById(R.id.textView);
// File on my sd card
File file = new File(Environment.getExternalStorageDirectory() + "/test.txt");
Uri myUri = Uri.fromFile(file);
Log.i("URI", myUri.toString());
//Create arguments
Bundle args = new Bundle();
args.putParcelable("URI", myUri);
getLoaderManager().initLoader(0, args, this);
}
#Override
public Loader onCreateLoader(int id, Bundle args) {
final Uri uri = args.getParcelable("URI");
Loader loader = new AsyncTaskLoader<String>(this) {
#Override
protected void onStartLoading() {
forceLoad();
}
#Override
public String loadInBackground() {
InputStream inputStream = null;
StringBuffer buf = new StringBuffer();
try {
inputStream = getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
if (inputStream != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String str = "";
while ((str = reader.readLine()) != null) {
buf.append(str + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return buf.toString();
}
};
return loader;
}
#Override
public void onLoadFinished(Loader<String> loader, String data) {
//Interact with UI Here
if(data != null)
txt.setText(data);
}
#Override
public void onLoaderReset(Loader loader) {
}
}
I made an android app for learning Java.
Now i like to write objects from a list with objects to a file.
like ...
private List<MyObjects> objects = new ArrayList<MyObjects>();
MyObjects is a extra class and implements "Serializable".
To write the objects in a file i use also a extra class.
Now my problem.
With the below Line i get a FileNotFoundException.
fos = new FileOutputStream(fileName);
When i change this Line with this Line ...
fos = ctx.openFileOutput(fileName, Context.MODE_PRIVATE);
... looks like good but after endig the code i can't find the file in data/data/myPakage/files/.
The file is not exist.
I read the last 4 days a lot of sites and tutorials about that but i can't find my mistake.
Please help my.
I don't need a solved code but a link to the right side or a pointer in my mistaken code is fine.
Sorry for my english. Is not my first language.
I am not sure with code parts you need to get a good overview. If you need more, please tell me.
Here parts of my main site
package com.example.myProject;
import android.os.Bundle;
import android.app.FragmentTransaction;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
public class ActivityMain extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout_calc);
TabAdapter = new TabPagerAdapter(getSupportFragmentManager());
}
}
Here parts of my fragment site
package com.example.myProject;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
public class Fragment_1 extends Fragment implements OnClickListener {
private Button btnOFF;
private List<Numbers> number = new ArrayList<Numbers>();
private View fragment_1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
this.fragment_1 = inflater.inflate(R.layout.fragment_layout, container, false);
this.btnOFF = (Button)elementary.findViewById(R.id.id_btnOFF_Elementary);
this.btnOFF.setOnClickListener(this);
this.number.add(new Numbers());
// Here i try to get my data back from the file.
// Every time i get the information; The file not exist
// Perhaps the "containsAll" are wrong. But this is in the moment not my problem.
this.number.containsAll(StreamControl.importNumbers(this.getActivity()));
return fragment_1;
}
#Override
public void onClick(View buttonView) {
if (buttonView == this.btnOFF) {
// Here i try to export data over extra class -- see below
// I put in my List with objects calls "number" and information
// for "Context" i hope.
StreamControl.exportNumbers(number, this.getActivity());
}
}
}
Parts of my class Numbers
package com.example.myProject;
import java.io.Serializable;
public class Numbers implements Serializable {
private static final long serialVersionUID = -5384438724532423282L;
.
.
.
}
Here the code from the file "in" and "out"
package com.example.myProject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
public class StreamControl {
public static void exportNumbers(List<Numbers> number, Context ctx) {
String fileName = "MyCacheFile.ser";
File cacheFile = new File(fileName);
FileOutputStream fos = null;
try {
// With this line is it not working everytime.
// File not found exception
// But to make my own file with "createNewFile()" is not working
// in data/data i have just read permission.
fos = new FileOutputStream(cacheFile);
// If i use this line i have less problems.
// All Informations "i used Toast on a lot of places" was god.
// But after it, it was nowhere a file to found.
//fos = ctx.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(fos);
oos.writeInt(number.size());
for (int i =0; i < number.size(); i++) {
oos.writeObject(new Numbers(((Numbers)number.get(i)).getNumbers()));
}
}
catch (IOException e1) { e1.printStackTrace(); }
finally {
try {
if (oos != null) { oos.close(); }
}
catch (IOException ex) { }
}
}
catch (FileNotFoundException e2) { e2.printStackTrace(); }
finally {
try {
if (fos != null) { fos.close(); }
}
catch (IOException ex) { ex.printStackTrace(); }
}
}
public static List<Numbers> importNumbers(Context ctx) {
String fileName = "MyCacheFile.ser";
int count = 0;
List<Numbers> number = new ArrayList<Numbers>();
FileInputStream fis = null;
try {
fis = new FileInputStream(fileName);
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(fis);
count = ois.readInt();
for (int i = 0; i < count; i++) {
number.add(new Numbers(((Numbers) ois.readObject()).getNumbers()));
}
}
catch (IOException ex) { ex.printStackTrace(); }
catch (ClassNotFoundException ex) { ex.printStackTrace(); }
finally {
try {
if (ois != null) { ois.close(); }
}
catch (IOException ex) { ex.printStackTrace(); }
}
}
catch (FileNotFoundException ex) { ex.printStackTrace(); }
finally {
try {
if (fis != null) { fis.close(); }
}
catch (IOException ex) { ex.printStackTrace(); }
}
return number;
}
}
So, i hope that's are enough information.
I looking forward
When you use Context.openFileOutput you create a file in internal storage and you can't check that directory.
Take a look at this to save a file to external storage