Android takePicture doesn't call callback method onPictureTaken() - java

I am working on a hidden camera application but I have some problems with taking photo.
When I debug the application, I can see that takePicture can be invoked but it doesn't call pictureCallback class.
I am putting class I am using and waiting for your helps.
public class TakePhotoClass {
private final String LOG_TAG="Photo Taker Class";
private Context context;
private Camera cam;
private Camera.PictureCallback pictureCallback;
private AudioManager audioManager;
public TakePhotoClass(Context con) {
// TODO Auto-generated constructor stub
context=con;
audioManager=(AudioManager) con.getSystemService(Context.AUDIO_SERVICE);
}
public void takePhoto(){
prepareCamera();
audioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
try{
cam.startPreview();
cam.takePicture(null, null, pictureCallback);
}catch(Exception ex)
{
Log.e(LOG_TAG, "Couldn't be taken photo. Error message: "+ex.getLocalizedMessage());
}
}
private void prepareCamera(){
cam=Camera.open();
Camera.Parameters param=cam.getParameters();
param.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
param.setJpegQuality(100);
param.setFocusMode(param.FOCUS_MODE_AUTO);
param.setPictureFormat(ImageFormat.JPEG);
cam.setParameters(param);
SurfaceView view=new SurfaceView(context);
try {
cam.setPreviewDisplay(view.getHolder());
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e(LOG_TAG, "Can not set surface");
}
setCallback();
}
private void setCallback(){
pictureCallback=new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
try{
File parentFolder=new File(Environment.getExternalStorageDirectory()+"/Agent Cam/Photo");
File photoFile=new File(parentFolder,"photo_"+getPhotoTime()+".jpg");
if(!photoFile.exists())
photoFile.mkdirs();
FileOutputStream stream=new FileOutputStream(photoFile);
stream.write(data);
stream.flush();
stream.close();
audioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+Environment.getExternalStorageDirectory())));
camera.release();
}catch(Exception ex)
{
Log.e(LOG_TAG, "Photo coluldn't be saved. Error message: "+ex.getLocalizedMessage());
}
}
};
}
private String getPhotoTime(){
SimpleDateFormat sdf=new SimpleDateFormat("ddMMyy_hhmmss");
return sdf.format(new Date());
}
}

Camera.PictureCallback's method onPictureTaken is called asynchronously (see takePicture), your app should wait for it to be called.

Related

Prevent Android Studio Flutter app from closing after taking a picture

I am busy developing a APP On Android Studio using the Flutter framework, that functions as follows,
The user can press press a button and it will take a picture without opening the camera view.
I have a MethodChannel between my Dart/Flutter and Android.Java ,I am able to press the button and the app takes a pic and saves it to gallery.
The issue I am having is that it closes the app afterwards with no error.
Could you please have a look at my code and see if you can help me.
MainActivity.Java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
#Override
public void onMethodCall(MethodCall call, Result result) {
if(call.method.equals("test"))
{
StartCameraFrontCamera();
}
else {
result.notImplemented();
}
}
});
}
public void StartCameraFrontCamera()
{
File directory = new File(Environment.getExternalStorageDirectory() + "/PicturesTest/");
if (!directory.exists()) {
directory.mkdir();
}
try {
ReleaseCamera();
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
} catch (Exception e) {
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPictureFormat(ImageFormat.JPEG);
mCamera.setParameters(parameters);
SurfaceView mview = new SurfaceView(this);
SurfaceTexture surfaceTexture = new SurfaceTexture(0);
imageName = "fontcamera.jpg";
try{
//mCamera.setPreviewDisplay(mview.getHolder());
mCamera.setPreviewTexture(surfaceTexture);
//mCamera.setPreviewDisplay(null);
mCamera.startPreview();
mCamera.takePicture(null,null,photoCallback);
//mCamera.stopPreview();
}catch(IOException e) {
e.printStackTrace();
}
}
Camera.PictureCallback photoCallback=new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
try {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/PicturesTest");
File file = new File (myDir, "image1.jpg");
FileOutputStream out = new FileOutputStream(file);
out.write(data);
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
}
finish();
}
};

How to download a file after clicking a button (Android Studio)

I recently created an activity in my app. Now I wanted the user to download a .pdf file when he/she wants to view the guidelines. I wanted to implement this on a button. Any idea how to do this properly?
Heres my code below:
public class Exhibitor_Registration_Activity extends AppCompatActivity {
Button buttonDownload;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exhibitor_registration_);
this.setTitle("Buyer Registration");
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
myToolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
final Button buttonDownload = (Button) findViewById(R.id.buttonDownload);
buttonDownload.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
try {
//this is the file you want to download from the remote server
String path ="http://www.manilafame.com/website-assets/downloads/exhibitor-application-kit/local/201704/1-Summary-of-Participation-Details-April-2017_MN_002.pdfp";
//this is the name of the local file you will create
String targetFileName = null;
boolean eof = false;
URL u = new URL(path);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File("c:\\junk\\"+targetFileName));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) > 0 ) {
f.write(buffer,0, len1);
}
f.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
I also got the source code from here and here.
if you want resumable, speed of download ...
follow this steps
create a class DownloadManager.java
public class DownloadManager extends AsyncTask<String,String,String>{
String downloadlink,fileDestination;
public static final int ON_INIT=100,ON_ERROR=102,ON_PROGRASS=103,ON_COMPLETED=104,STATUS_DOWNLOADED=1500,STATUS_NOT_YET=1501;
private onUpdateListener onUpdateListener;
private String downloadedPath="";
private long downloaded=0;
private File file;
private String returnData=null;
private File cacheDownloadFile;
public DownloadManager(String downloadlink,String fileDestinationPath){
this.downloadlink=downloadlink;
this.fileDestination=fileDestinationPath;
file=new File(fileDestination, Tools.getFileName(downloadlink));
cacheDownloadFile=new File(AppCostants.CHACHE_PATH+Tools.getFileName(downloadlink));
try {
if(cacheDownloadFile.isFile())
downloaded=Tools.getFileSize(cacheDownloadFile);
else
downloaded=0;
Log.d("FILE_DOWNLOAD_TAG_p",downloaded+" <- "+cacheDownloadFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
fireOnUpdate(ON_INIT,"init ...");
}
#Override
protected String doInBackground(String... params) {
try {
File dir=new File(fileDestination);
File chacheDir=new File(AppCostants.CHACHE_PATH);
if(!chacheDir.isDirectory())
chacheDir.mkdirs();
if(!dir.isDirectory()){
dir.mkdirs();
}
if(file.exists()) {
Log.d("FILE_DOWNLOAD_TAG","File exist return complete");
return "COMPLETED";//file exist
}
if(!cacheDownloadFile.exists()){
cacheDownloadFile.createNewFile();
}
Log.d("FILE_DOWNLOAD_TAG","LINK "+downloadlink);
URL url=new URL(downloadlink);
HttpURLConnection urlConnection= (HttpURLConnection) url.openConnection();
if(downloaded>0)
urlConnection.setRequestProperty("Range","byte="+downloaded);
urlConnection.connect();
int status = urlConnection.getResponseCode();
InputStream inputStream=urlConnection.getInputStream();
int totalSize=urlConnection.getContentLength();
if(totalSize<=downloaded){
returnData= "COMPLETED";
publishProgress("File checked "+Tools.getFileName(file.getAbsolutePath()));
return returnData;
}
this.downloadedPath=cacheDownloadFile.getAbsolutePath();
byte[] buffer=new byte[1024];
int bufferLength=0;
FileOutputStream fileOutput=new FileOutputStream(cacheDownloadFile);
long d=0;
long starttime=System.currentTimeMillis();
while ((bufferLength=inputStream.read(buffer))>0){
fileOutput.write(buffer,0,bufferLength);
downloaded+=bufferLength;
d+=bufferLength;
//String l=" "+Tools.getFileName(file.getAbsolutePath())+" ( "+Tools.convertMemory(downloaded)+" / "+Tools.convertMemory(totalSize)+" )";
String l=" "+Tools.convertMemory(downloaded)+" / "+Tools.convertMemory(totalSize)+" ( "+getDownloadSpeed(starttime,d)+" )";
publishProgress(l);
if(downloaded>=totalSize){
break;
}
}
Log.d("FILE_DOWNLOAD_TAG","DWONLOADED TO "+downloadedPath+" ("+cacheDownloadFile.length()+")");
fileOutput.close();
if(Tools.fileCopy(file,cacheDownloadFile)){
Log.d("FILE_DOWNLOAD_TAG","file Copied, delete cache");
cacheDownloadFile.delete();
}
returnData="COMPLETED";
} catch (MalformedURLException e) {
returnData=null;
e.printStackTrace();
publishProgress(e.toString());
Log.d("###################",e+"");
} catch (IOException e) {
returnData=null;
e.printStackTrace();
publishProgress(e.toString());
}
return returnData;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
fireOnUpdate(ON_PROGRASS,values[0]);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(s!=null){
fireOnUpdate(ON_COMPLETED,downloadedPath);
}else{
fireOnUpdate(ON_ERROR,"Download failed");
}
}
public interface onUpdateListener{
void onUpdate(int code,String message);
}
public void setOnUpdateListener(onUpdateListener onUpdateListener){
this.onUpdateListener=onUpdateListener;
}
private void fireOnUpdate(int code,String message){
if(onUpdateListener!=null)
onUpdateListener.onUpdate(code,message);
}
private String getDownloadSpeed(long starttime,float totalDownloaded) {
long elapsedTime = System.currentTimeMillis() - starttime;
//byte :
float speed=1000f * totalDownloaded / elapsedTime;
return convert(speed);
}
private String convert(float value){
long kb=1024
,mb=kb*1024
,gb=mb*1024;
if(value<kb){
String speed=(value+"");
speed=speed.substring(0,speed.indexOf('.')+2);
return speed+" B/s";
}else if(value<mb){
value=value/kb;
String speed=(value+"");
speed=speed.substring(0,speed.indexOf('.'));
return (speed)+" KB/s";
}else if(value<gb){
value=(value/mb);
String speed=(value+"");
speed=speed.substring(0,speed.indexOf('.'));
return speed+" MB/s";
}
return "";
}
}
use this code in onClick()
DownloadManager downloadManager = new DownloadManager(url,filepath);
set event
downloadManager.setOnUpdateListener(new DownloadManager.onUpdateListener() {
#Override
public void onUpdate(int code, String message) {
if (code == DownloadManager.ON_COMPLETED) {
}
if(DownloadManager.ON_PROGRASS==code){}
}
});
start download by
downloadManager.execute();
lib setup
compile "commons-io:commons-io:+"
Tools.java
public static long getFileSize(File file) throws IOException {
FileOutputStream fileOutputStream=new FileOutputStream(file);
fileOutputStream.close();
return file.length();
}
public static boolean fileCopy(File dest,File source){
try {
FileUtils.copyFile(source,dest);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
It is really bad idea to download file in main thread.
Use separate Thread for this
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
//your downloading here
}
});
thread.start();
it`s better, but still not so good. There are some problems with it:
1) User know nothing about downloading
So better to show additional layout which overlays screen with progress bar, probably indeterminate if you want to write less code. Then after downloading is finished you just hide your layout.
You can use runOnUiThread inside run method in thread for it.
runOnUiThread(new Runnable() {
#Override
public void run() {
//just hide some popup
//or do what you want after downloading is finished
popupLayout.serVisibility(View.GONE);
}
});
2) If user will do action which re-creates activity/fragment (like changing screen orientaion) with running thread you will get memory leak and probably activity will not know about end of download.
There are few ways to solve this problem:
You can block screen orientation at this screen, at least while downloading. Probably easiest way in your case.
You can use downloading in foreground service. Its really good
practice, but you will have to learn about services.
You can try to interrupt downloading by calling thread.interrupt()
method in onDestroy of your Activity/Fragment
You can use something like rxJava/rxAndroid (so you don not use threads at all, but you need some time for learn rxJava)
UPD
About threads
Not so bad tutorial about threads in android
You can use AsyncTask instead of Thread, but I highly recommend to use threads especially for long operations.

Passing bitmap object to Mainactivity

i have a service in which my camera is taking a picture. Here is the code:
public class Picture_Service extends Service
{
//Camera variables
//a surface holder
private SurfaceHolder sHolder;
//a variable to control the camera
private Camera mCamera;
//the camera parameters
private Parameters parameters;
private int i = 0;
private static final int DISCOVER_DURATION = 300;
// our request code (must be greater than zero)
private static final int REQUEST_BLU = 1;
/** Called when the activity is first created. */
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
mCamera = Camera.open();
SurfaceView sv = new SurfaceView(getApplicationContext());
try {
mCamera.setPreviewDisplay(sv.getHolder());
parameters = mCamera.getParameters();
//set camera parameters
mCamera.setParameters(parameters);
mCamera.startPreview();
mCamera.takePicture(null, null, mCall);
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(this, "Logged in as Administrator!",Toast.LENGTH_LONG).show();
Log.w("Display Hona Chahye", "Kr dia na display Rami");
e.printStackTrace();
}
//Get a surface
sHolder = sv.getHolder();
//tells Android that this surface will have its data constantly replaced
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
Camera.PictureCallback mCall = new Camera.PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera)
{
//decode the data obtained by the camera into a Bitmap
FileOutputStream outStream = null;
try{
i++;
Log.w("Rami Rami","maha harami");
Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data.length);
//outStream = new FileOutputStream("/sdcard/Image.jpg");
//outStream.write(data);
//Bitmap yourSelectedImage = BitmapFactory.decodeFile("/sdcard/Image.jpg");
//BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
Log.w("Rami insan","Rami write hogya");
mCamera.release();
outStream.close();
} catch (FileNotFoundException e){
Log.d("CAMERA", e.getMessage());
} catch (IOException e){
Log.d("CAMERA", e.getMessage());
}
}
};
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
1- My first question is would i get my image in the bitmap object here: ?
Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data.length);
2- Secondly, i want to pass this object to the mainactivity. How will i do that??
You can convert your image to a String and pass it to MainActivity.
convert your image into a byte array though. Here's an example:
Bitmap bm = BitmapFactory.decodeFile("/path/to/image.jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
And encode it to base64 :
String encodedImage = Base64.encodeToString(byte, Base64.DEFAULT);
byte[] bytearray = Base64.decode(encodedImage);
FileOutputStream imageOutFile = new FileOutputStream("after_convert.jpg");
imageOutFile.write(bytearray);

Android turn on/off mobile data using code

I am trying to approach a problem in which I have to disable and then enable mobile data with some delay in between (reset mobile data 2G).
step 1: disable mobile data
step 2: wait till mobile data gets disabled
step 3: some delay say 2 seconds
step 4: enable mobile data
step 5: wait till mobile data gets enabled
step 6: continue with the program.....
doing some research I came up with this...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button start = (Button)findViewById(R.id.button1);
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(!mobileDataEnabled(getApplicationContext())){
setMobileDataEnabled(getApplicationContext(),true);
Toast.makeText(getApplicationContext(), "ENABLED", Toast.LENGTH_SHORT).show();
}else{
setMobileDataEnabled(getApplicationContext(),false);
Toast.makeText(getApplicationContext(), "DISABLED", Toast.LENGTH_SHORT).show();
}
}
});
}
//the method below enables/disables mobile data depending on the Boolean 'enabled' parameter.
private void setMobileDataEnabled(Context context, boolean enabled) {
final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Class conmanClass = null;
try {
conmanClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// below method returns true if mobile data is on and vice versa
private boolean mobileDataEnabled(Context context){
boolean mobileDataEnabled = false; // Assume disabled
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
try {
Class cmClass = Class.forName(cm.getClass().getName());
Method method = cmClass.getDeclaredMethod("getMobileDataEnabled");
method.setAccessible(true); // Make the method callable
// get the setting for "mobile data"
mobileDataEnabled = (Boolean)method.invoke(cm);
} catch (Exception e) {
// Some problem accessible private API
// TODO do whatever error handling you want here
}
return mobileDataEnabled;
}
The above code will turn on/off mobile data but it happens really quick. this quick that the mobile data doesn't even turn off actually. how do I add a delay in between and achieve the steps I mentioned above? any help would be appreciated.
thanks!
Just put
Thread.sleep(1000);
in between the code statements (before setMobileData APIs) to achieve delay. The delay parameter is in milliseconds. So change it according to your requirement.
EDIT: Try putting the delay into a handler, using this code:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Whatever you want to do
}
}, 1000);
Try this may work. Use your code for turning off/on your packet data.
You should use a broadcast receiver for getting the events of connectivity.
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
Check the below link for details
Get notified on connectivity change
public void mobiledataenable(boolean enabled) {
try {
final ConnectivityManager conman = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
final Class<?> conmanClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
final Class<?> iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
}
catch (Exception e)
{
e.printStackTrace();
}
}
Try (this will turn the data off then wait till it's off then on again):
setMobileDataEnabled(getApplicationContext(),false);
while(mobileDataEnabled(getApplicationContext()){
//Just wait, don't do anything
}
//Turn it on here
setMobileDataEnabled(getApplicationContext(),true);
Lemme know if i couldn't get you properly!
// first check whether it is on\off...
public void setMobileDataEnabled(Context context, boolean status) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException
{
final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final Class conmanClass = Class.forName(conman.getClass().getName());
final Field connectivityManagerField = conmanClass.getDeclaredField("mService");
connectivityManagerField.setAccessible(true);
final Object connectivityManager = connectivityManagerField.get(conman);
final Class connectivityManagerClass = Class.forName(connectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = connectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(connectivityManager, status);
}

Shared Preference VS Context?

I'm not that much experienced in Android, so every piece of code I have written so far was very simple. Now I need to implement a localization and navigation application, so I need to break my code into modules so that I can change each component alone. I have some variables that I need to share them between different classes. I used static variables but I read in some posts here that static variables are not preferred. Then I found some other posts talking about Context. So I created a class named Globals and I added the following lines in my Manifest file:
<application android:name="com.example.smartnav.Globals"
package="com.example.smartnav"
android:icon="#drawable/ic_launcher"
android:allowBackup="true"
android:label="#string/app_name"/>
And here is the Globals Class :
package com.example.smartnav;
import java.util.List;
import android.net.wifi.ScanResult;
import android.app.Application;
public class Globals extends Application {
private Boolean Scanning=false;
private String Logname;
private int interval;
private int numOfScans;
private List<ScanResult> result;
//getters
public Boolean getScannig(){
return Scanning;
}
public int getInterval()
{
return interval;
}
public int getScans()
{
return numOfScans;
}
public List<ScanResult> getRes()
{
return result;
}
public String getLog()
{
return Logname;
}
//setter
public void setScanning(Boolean s){
Scanning= s;
}
public void setRes(List<ScanResult> res)
{
result =res;
}
public void setInterval(int I)
{
interval = I;
}
public void setScans(int S)
{
numOfScans=S;
}
public void setLog(String s)
{
Logname= s;
}
}
Now I have two questions, the first one is that my application keeps crashing whenever I try to use the Globals class, here is the code: Did I use context incorrectly?
public class MainActivity extends Activity {
private Context context;
public WifiManager Wifi;
private WifiReceiver receiverWifi;
private IntentFilter filter;
private List<ScanResult> result;
private File AppDir;
private static String filename;
private File file;
private FileWriter writer;
private Globals AppState ;
private int Interval;
private int numOfScans;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("Main ","activity created");
//
AppState = ((Globals)getApplicationContext());
context= this;
Wifi=(WifiManager) getSystemService(Context.WIFI_SERVICE);
receiverWifi = new WifiReceiver();
filter= new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(receiverWifi, filter);
Log.d("Main ","wifi registered");
// create the application directory
AppDir = new File(Environment.getExternalStorageDirectory()+"/SmartNavi/Log");
if(AppDir.isDirectory())
{
filename=Environment.getExternalStorageDirectory()+"/SmartNavi/Log/log.txt";
file = new File(filename);
if(!file.exists())
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
else
{
Date d= new Date();
filename=Environment.getExternalStorageDirectory()+"/SmartNavi/Log/log"+d.getTime()+".txt";
file = new File(filename);
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
else
{
AppDir.mkdirs();
filename=Environment.getExternalStorageDirectory()+"/SmartNavi/Log/log.txt";
file = new File(filename);
if(!file.exists())
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
else
{
Date d= new Date();
filename=Environment.getExternalStorageDirectory()+"/SmartNavi/Log/log"+d.getTime()+".txt";
file = new File(filename);
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//setting pars
Interval=250;
numOfScans=4;
AppState.setInterval(Interval);
AppState.setScans(numOfScans);
AppState.setLog(filename);
Wifi.startScan();
try {
writer = new FileWriter(file, true);
writer.append("Smart Navigation. \n");
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// AsyncScanning.AsyncScan();
}//on create
#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;
}
class WifiReceiver extends BroadcastReceiver {
public void onReceive(Context c, Intent intent) {
result=Wifi.getScanResults();
// AppState.setRes(result);
try {
writer = new FileWriter(file, true);
writer.append(result.size()+" s \n");
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//end of on receive
}// end of class
} // end of smartNav
My last question is this : I have read on some answers here that if my application becomes a background process then all the data in the context will be set to null, and I will lose my context. Is there is any method to overcome this point? or should I switch to SharedPreferences ?
Edit :Here is the output of Logcat
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.smartnav/com.example.smartnav.MainActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.example.smartnav.Globals
Now I have two questions, the first one is that my application keeps crashing whenever I try to use the Globals class, here is the code: Did I use context incorrectly?
you should use getApplication() method for that, or make your application class singleton, so you would call Globals.getInstance().getMyVariable() etc.
My last question is this : I have read on some answers here that if my application becomes a background process then all the data in the context will be set to null, and I will lose my context. Is there is any method to overcome this point? or should I switch to SharedPreferences ?
if your app becomes background then Android is more likely to kill your app, and this way also destroy all your static objects. Inside your Globals class you should not store your data in static variables but rather in some persistant storage - if its small then use SharedPreferences, if its large then you can store it in json and save to application memory, or use sqlite db.

Categories

Resources