I am making an android app in which i need to take the users location through fused location provider. Before taking the location i want to check whether the gps is on or not. And i want to do this without using location manager. Any suggestions?
Throw bellow method you can check Location Mode,
/**
* Method is used to check which locatrion mode is selected,
*
* #param context
* #return If return 0 = LOCATION_MODE_OFF, 1 = LOCATION_MODE_SENSORS_ONLY & DEVICE_ONLY, 2 = LOCATION_MODE_BATTERY_SAVING , 3 = LOCATION_MODE_HIGH_ACCURACY
*/
public static int getLocationMode(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
return Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
return 0;
}
} else {
try {
String locationProviders = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED
);
if (!TextUtils.isEmpty(locationProviders)) {
return 2;
} else {
return 0;
}
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
private void checkGpsEnabled() {
LocationSettingsRequest settingsRequest = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest)
.setNeedBle(true)
.setAlwaysShow(true)
.build();
SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> response = client.checkLocationSettings(settingsRequest);
response.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
}
});
response.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
if (e instanceof ResolvableApiException) {
ResolvableApiException resolvableApiException = (ResolvableApiException) e;
try {
resolvableApiException.startResolutionForResult(LocationFusedActivity.this, 1002);
} catch (IntentSender.SendIntentException e1) {
e1.printStackTrace();
}
}
}
});
}
Related
How to handle this kind of exception? Given work is not active exception in Oreo while i m using unique job id across the app.
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:353)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.IllegalArgumentException: Given work is not active: JobWorkItem{id=2 intent=Intent { cmp=com.virinchi.mychat/com.virinchi.receiver.AnalysticsSubmit } dcount=1}
at android.app.job.JobParameters.completeWork(JobParameters.java:221)
at android.support.v4.app.JobIntentService$JobServiceEngineImpl$WrapperWorkItem.complete(JobIntentService.java:267)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:393)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:382)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask)
public class AnalysticsSubmit extends JobIntentService {
private static String TAG = "AnalysticsSubmit";
/**
* Unique job ID for this service.
*/
/**
* Convenience method for enqueuing work in to this service.
*/
public static void enqueueWork(Context context, Intent work) {
try{
enqueueWork(context, AnalysticsSubmit.class, JOB_ID, work);
}catch (Exception ex){
Log.e(TAG, "enqueueWork: ex"+ex.getMessage() );
}
}
#Override
protected void onHandleWork(Intent intent) {
try {
UtilsUserInfo userInfo = new UtilsUserInfo(DocApplication.getContext());
int width = 0;
int height = 0;
String widthstr = "0";
String heightstr = "0";
JSONObject records = new JSONObject();
JSONObject device_info = new JSONObject();
WindowManager wm = (WindowManager) DocApplication.getContext().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(displayMetrics);
width = displayMetrics.widthPixels;
height = displayMetrics.heightPixels;
widthstr = String.valueOf(width);
heightstr = String.valueOf(height);
String device_model = Build.MODEL + " " + Build.VERSION.RELEASE;
device_info.put("app_version", userInfo.getFromPreferences("version"));
device_info.put("operating_system", getOsName());
device_info.put("device_resolution", widthstr + "*" + heightstr);
device_info.put("device_model", device_model);
device_info.put("device_manufacturer", Build.MANUFACTURER);
device_info.put("app_identifier", ResourceUtils.getResourceString(this, R.string.app_identifier_analytics));
JSONArray event = new JSONArray();
try {
Realm realm = SingleInstace.getInstace().getRealm();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
try {
JSONObject eventobj = null;
RealmResults<DocquityLog> results = realm.where(DocquityLog.class).findAll();
results.load();
for (DocquityLog obj : results) {
JSONObject session_time = new JSONObject();
JSONObject location = new JSONObject();
eventobj = new JSONObject();
eventobj.put("event_name", obj.getEvent_name());
eventobj.put("product_type", obj.getProduct_type());
eventobj.put("product_type_id", obj.getProduct_type_id());
eventobj.put("session_id", obj.getSession_id());
eventobj.put("local_id", obj.getId());
eventobj.put("screen_name", obj.getScreen_name());
if (!Validation.isEmptyString(userInfo.getFromPreferences("user_id"))) {
eventobj.put("user_id", Integer.parseInt(userInfo.getFromPreferences("user_id")));
if (userInfo.isKeyExist("untrack_user_identifier")) {
eventobj.put("untrack_user_identifier", userInfo.getFromPreferences("untrack_user_identifier"));
userInfo.removeKey("untrack_user_identifier");
}
} else {
eventobj.put("user_id", 0);
eventobj.put("untrack_user_identifier", userInfo.getFromPreferences("untrack_user_identifier"));
}
session_time.put("start_time", obj.getStart_time());
session_time.put("end_time", obj.getEnd_time());
eventobj.put("session_time", session_time);
location.put("latitude", obj.getLatitude());
location.put("longitude", obj.getLongitude());
location.put("local", obj.getLocal());
location.put("time_zone", obj.getTime_zone());
eventobj.put("location", location);
event.put(eventobj);
}
} catch (Exception ex) {
LogEx.logExecption(TAG, "", ex);
}
}
});
} catch (Exception ex) {
LogEx.logExecption(TAG, "", ex);
} finally {
SingleInstace.getInstace().destroyRealm();
}
records.put("device_info", device_info);
records.put("event", event);
// Log.e(TAG, " records "+records.toString());
if (records != null && event.length() > 0) {
//apiAnalysticWork(records.toString());
ApiManager.getClientBasicAuthNewReactive(userInfo.getFromPreferences("user_auth_key"),
userInfo.getFromPreferences(userInfo.token_id),
ApiManager.GENRIC_API_VERSION_2, userInfo.getFromPreferences("version"),
GlobalSetting.Lng, "", ApiManager.DeviceType).getAnalysticRecord(records.toString())
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.computation())
.subscribe(searchResponse -> {
try {
int status = searchResponse.getStatus();
if (status == 1) {
// Log.e(TAG, "showSearchResult: success");
// delete work
try {
Realm realm = SingleInstace.getInstace().getRealm();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
try {
RealmQuery q = realm.where(DocquityLog.class);
int x = 0;
for (Integer id : searchResponse.getAnalysticData().getSuccess_session_ids()) {
if (x != 0) {
q.or();
}
q = q.equalTo("id", id);
x++;
}
RealmResults<DocquityLog> filteredArticles = q.findAll();
filteredArticles.deleteAllFromRealm();
} catch (Exception ex) {
Log.e(TAG, " ex " + ex.getMessage());
Crashlytics.logException(ex);
}
}
});
} finally {
SingleInstace.getInstace().destroyRealm();
}
//RealmController.commitInput();
}
} catch (Exception ex) {
LogEx.logExecption(TAG, "", ex);
}
}, throwable -> LogEx.displayRetrofitError(TAG, throwable));
// Log.e(TAG, "jsonWorkAnalystic:reords "+records.toString() );
}
} catch (JSONException e) {
LogEx.logExecption(TAG, "JSONException", e);
} catch (Exception e) {
LogEx.logExecption(TAG, "OtherException", e);
}
}
/*public AnalysticsSubmit() {
super("AnalysticsSubmit");
}
#Override
public void onDestroy() {
// Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
#Override
protected void onHandleWork(#NonNull Intent intent) {
}
*/
public String getOsName() {
StringBuilder builder = new StringBuilder();
// builder.append("android : ").append(Build.VERSION.RELEASE);
Field[] fields = Build.VERSION_CODES.class.getFields();
for (Field field : fields) {
String fieldName = field.getName();
int fieldValue = -1;
try {
fieldValue = field.getInt(new Object());
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
if (fieldValue == Build.VERSION.SDK_INT) {
builder.append(fieldName);
}
}
return builder.toString();
}
}
Following is my code and I want to get push notification when my device is offline or app is killed.
When my app is background I want to get notify by XMPP ejabberd server
IQ Class
class MyCustomIQ extends IQ {
String token = SharedPreferenceManager.getValue(getApplicationContext(), "DEVICE_TOKEN");
protected MyCustomIQ() {
super("query", "urn:xmpp:registernoti");
}
#Override
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
xml.rightAngleBracket();
xml.element("token", token);
xml.element("devicetpye", "android");
return xml;
}
}
On connected
#Override
public void connected(XMPPConnection connection) {
Log.e(TAG, "connected: ");
MyCustomIQ iq = new MyCustomIQ();
iq.setType(IQ.Type.set);
try {
abstractXMPPConnection.sendIqWithResponseCallback(iq, new StanzaListener() {
#Override
public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
Log.e(TAG, "processStanza: " + packet.toString());
}
});
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Try following code for register device token on xmpp server
Register token stanza
<iq to="YourServer" type="set">
<register xmlns="https://android.googleapis.com/gcm" >
<key>API_KEY</key>
</register>
</iq>
1) way for register token
public void registerTokenTomod_gcm(final String deviceToken){
IQ iq=new IQ("register","https://android.googleapis.com/gcm") {
#Override
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
xml.attribute("key",deviceToken);
xml.setEmptyElement();
return xml;
}
};
iq.setType(IQ.Type.set);
iq.setTo(AppConstants.CHAT_HOSTNAME);
debugLog("getpushDicsoInfo send stanza:"+iq.toXML());
try {
if(connection.isSmEnabled()) {
debugLog("sm enabled");
try {
connection.addStanzaIdAcknowledgedListener(iq.getStanzaId(), new StanzaListener() {
#Override
public void processPacket(Stanza stanza) throws SmackException.NotConnectedException {
debugLog("SendMessage addStanzaIdAcknowledgedListener ::" + stanza.toXML());
if(registerXmppListener!=null){
registerXmppListener.onStanzaIdAcknowledgedReceived(stanza);
}
}
});
} catch (StreamManagementException.StreamManagementNotEnabledException e) {
e.printStackTrace();
}
}
connection.sendStanza(iq);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
2) way to register token
public void registerTokenToXmpp(String deviceId,String deviceName,String deviceToken){
DataForm xep0004 = new DataForm(DataForm.Type.submit);
FormField token = new FormField("token");
token.addValue(deviceToken);
FormField device_id = new FormField("device-id");
device_id.addValue(deviceId);
FormField device_name = new FormField("device-name");
device_name.addValue(deviceName);
xep0004.addField(token);
xep0004.addField(device_id);
xep0004.addField(device_name);
AdHocCommandData stanza = new AdHocCommandData();
stanza.setTo("android");
stanza.setType(IQ.Type.set);
stanza.setStanzaId("0043423");
stanza.setNode("register-push-gcm");
stanza.setAction(AdHocCommand.Action.execute);
stanza.setForm(xep0004);
stanza.setFrom(connection.getUser());
debugLog("getpushDicsoInfo send stanza:"+stanza.toXML());
try {
if(connection.isSmEnabled()) {
debugLog("sm enabled");
try {
connection.addStanzaIdAcknowledgedListener(stanza.getStanzaId(), new StanzaListener() {
#Override
public void processPacket(Stanza stanza) throws SmackException.NotConnectedException {
debugLog("SendMessage addStanzaIdAcknowledgedListener ::" + stanza.toXML());
if(registerXmppListener!=null){
registerXmppListener.onStanzaIdAcknowledgedReceived(stanza);
}
}
});
} catch (StreamManagementException.StreamManagementNotEnabledException e) {
e.printStackTrace();
}
}
connection.sendStanza(stanza);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
UnRegister device token from server
private void unregisterToken(){
String deviceid="3524940..."; //sony
String tokenstring="GHkd7Ro2qtMg:XPA91bflkgklDeg..."; // sony
DataForm xep0004 = new DataForm(DataForm.Type.submit);
FormField token = new FormField("token");
token.addValue(tokenstring);
FormField device_id = new FormField("device-id");
device_id.addValue(deviceid);
FormField device_name = new FormField("device-name");
// device_name.addValue(devicename);
xep0004.addField(token);
xep0004.addField(device_id);
xep0004.addField(device_name);
AdHocCommandData stanza = new AdHocCommandData();
stanza.setTo("android");
stanza.setType(IQ.Type.set);
stanza.setStanzaId("0043423");
stanza.setNode("register-push-gcm");
stanza.setAction(AdHocCommand.Action.execute);
stanza.setForm(xep0004);
stanza.setFrom(connection.getUser());
debugLog("getpushDicsoInfo send stanza:"+stanza.toXML());
try {
if(connection.isSmEnabled()) {
debugLog("sm enabled");
try {
connection.addStanzaIdAcknowledgedListener(stanza.getStanzaId(), new StanzaListener() {
#Override
public void processPacket(Stanza stanza) throws SmackException.NotConnectedException {
debugLog("SendMessage addStanzaIdAcknowledgedListener ::" + stanza.toXML());
if(registerXmppListener!=null){
registerXmppListener.onStanzaIdAcknowledgedReceived(stanza);
}
}
});
} catch (StreamManagementException.StreamManagementNotEnabledException e) {
e.printStackTrace();
}
}
connection.sendStanza(stanza);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
}
I was download epson android sdk from
https://download.epson-biz.com/modules/pos/index.php?page=single_soft&cid=5228&pcat=7&pid=4179.
I have an Epson TM-T81 series printer,When i try to connect this sdk with my printer it show Error code(ERR_UNSUPPORTED),but when i change the printer series to TM-T82 or some other from the spinner, it works fine with my TM-T81 printer but it is not working when i select TM-T81.What is the reason for that?
You can use like this. This answer Will Help you.
public boolean initializeObject(Printer printerSeries) {
try {
// mPrinter=new Printer(Printer.TM_T88,Printer.LANG_EN,mContext);
or
mPrinter=new Printer(printerSeries,Printer.LANG_EN,mContext);
}
catch (Exception e) {
ShowMsg.showException(e, "Printer", mContext);
return false;
}
mPrinter.setReceiveEventListener(new com.epson.epos2.printer.ReceiveListener() {
#Override
public void onPtrReceive(Printer printer, int i, PrinterStatusInfo printerStatusInfo, String s) {
runOnUiThread(new Runnable() {
#Override
public synchronized void run() {
disconnectPrinter();
new Thread(new Runnable() {
#Override
public void run() {
disconnectPrinter();
}
}).start();
}
});
}
});
return true;
}
public void finalizeObject() {
if (mPrinter == null) {
return;
}
mPrinter.clearCommandBuffer();
mPrinter.setReceiveEventListener(null);
mPrinter = null;
}
public boolean printData(String receiptPrintIP) {
if (mPrinter == null) {
return false;
}
if (!connectPrinter(receiptPrintIP)) {
return false;
}
PrinterStatusInfo status = mPrinter.getStatus();
if (!isPrintable(status)) {
ShowMsg.showMsg(printPOS2Help.makeErrorMessage(status), mContext);
try {
mPrinter.disconnect();
}
catch (Exception ex) {
// Do nothing
}
return false;
}
try {
mPrinter.sendData(Printer.PARAM_DEFAULT);
}
catch (Exception e) {
ShowMsg.showException(e, "sendData", mContext);
try {
mPrinter.disconnect();
}
catch (Exception ex) {
// Do nothing
}
return false;
}
return true;
}
public boolean connectPrinter(String receiptPrintIP) {
boolean isBeginTransaction = false;
if (mPrinter == null) {
return false;
}
try {
mPrinter.connect(receiptPrintIP, Printer.PARAM_DEFAULT);
}
catch (Exception e) {
ShowMsg.showException(e, "connect", mContext);
return false;
}
try {
mPrinter.beginTransaction();
isBeginTransaction = true;
}
catch (Exception e) {
ShowMsg.showException(e, "beginTransaction", mContext);
}
if (isBeginTransaction == false) {
try {
mPrinter.disconnect();
}
catch (Epos2Exception e) {
// Do nothing
return false;
}
}
return true;
}
i wanna add user to signalR group but it says failed.
my android code to add user in group as below
HubConnection connection = new HubConnection("http://www.planetskool.in/");
HubProxy proxy = connection.createHubProxy("ChatHub");
try {
//Log.d(TAG, "connection.start()...");
SignalRFuture<Void> awaitConnection = connection.start();
// Log.d(TAG, "started");
awaitConnection.get();
// Log.d(TAG, "got");
} catch (InterruptedException e) {
/// Log.e(TAG,"InterruptedException");
e.printStackTrace();
} catch (ExecutionException e) {
//Log.e(TAG, "ExecutionException");
e.printStackTrace();
}
SignalRFuture<Void> isGroupCreated2 = proxy.invoke("JoinGroup", loginUserInfoId);
Log.d("isGroupCreated", "isGroupCreated2 = " + proxy.invoke("JoinGroup", loginUserInfoId).isDone());
proxy.on("broadcastMessage",
new SubscriptionHandler1<String>() {
#Override
public void run(final String status) {
//getApplicationContext().runOnUiThread(new Runnable() {
//public void run() {
Log.d("SignalRResult=", status);
if(status.toUpperCase().equals("False".toUpperCase())) {
new SyncMessageFromServer().execute();
}
else {
new SyncGroupMessageFromServer().execute();
}
// }
//});
}
}
, String.class);
and the code in ChatHub in MVC Web Application is
public Task JoinGroup(string groupName)
{
return Groups.Add(Context.ConnectionId, groupName);
}
public void SendAll(string rUId, string message)
{
Clients.Group(rUId).broadcastMessage(message);
}
How can i make it work to send notification to particular user
I have read similar threads and haven't found an answer which would solve my problem.
I am writing an app with 2 different MediaRecorders. One for noise detection and another one for recording. What I want to do is - when the first MediaRecorder detects noise levels above 4.0 (I am using Google's SoundMeter class for detection) it will initiate another MediaRecorder and start recording. If the soundlevels stay below 4.0 for 10 seconds, then stop recording and keep listening. All of this is done in an AsynTask, in an endless while(true) loop, which will be broken, only if a corresponding button is clicked.
The detection is working fine, but the IllegalStateException is thrown when start() is called on the recording MediaRecorder.
Here is the AsyncTask:
private class NoiseDetection extends AsyncTask {
double currentSoundInputLevel;
#Override
protected Object doInBackground(Object[] params) {
int i = 0;
soundMeter = new SoundMeter();
try {
soundMeter.start();
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("error", e.getMessage());
}
if(isCancelled()){
soundMeter.stop();
if(currentlyRecording) {
soundRecorder.stop();
}
break;
}
currentSoundInputLevel = soundMeter.getAmplitudeEMA();
if(!currentlyRecording && currentSoundInputLevel > 4.0){
soundRecorder = new SoundRecorder();
try {
soundRecorder.start(getFileNameString());
currentlyRecording = true;
} catch (IOException e) {
Log.e("error", e.getMessage());
}
} else if(currentlyRecording && currentSoundInputLevel < 4.0) {
i++;
if(i > 10) {
soundRecorder.stop();
}
}
}
return null;
}
}
And here is the SoundRecorder:
public class SoundRecorder {
private MediaRecorder mRecorder = null;
public void start(String fileName) throws IOException {
if (mRecorder == null) {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mRecorder.setOutputFile(Environment.getExternalStorageDirectory().getPath() + "/" + fileName);
mRecorder.prepare();
mRecorder.start();
}
}
public void stop() {
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
}
The exception is thrown on mRecorder.start();.
I think the problem lies within the idea of doing everything in this while loop, but I haven't come up with a better idea of achieving the forementioned goal.
Also, I have tried different OutputFormats and AudioEncoders without success. (reference to https://stackoverflow.com/a/23065021/1826152)
Another note, which could be of use, is the fact that the file is actually created in the sdcard dir.
The phone I am using for development is a Nexus 5. The permissions in android manifest are the following:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Update:
Right now I have tried to remove the SoundRecorder operations from the while loop by creating a RecordingHandler. The new code for the doInBackground() is as follows:
protected Object doInBackground(Object[] params) {
int i = 0;
soundMeter = new SoundMeter();
RecordingHandler recordingHandler = null;
try {
soundMeter.start();
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
if(isCancelled()){
soundMeter.stop();
if(currentlyRecording && recordingHandler != null){
recordingHandler.kill();
}
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("error", e.getMessage());
}
if(!currentlyRecording && soundMeter.getAmplitudeEMA() > 4.0){
recordingHandler = new RecordingHandler(deviceId);
currentlyRecording = true;
recordingHandler.run();
}
}
return null;
}
and the RecordingHandler itself is the following:
public class RecordingHandler implements Runnable {
SoundRecorder soundRecorder;
SoundMeter soundMeter;
String deviceID;
boolean isKilled = false;
public RecordingHandler(String deviceID){
this.soundRecorder = new SoundRecorder();
this.soundMeter = new SoundMeter();
this.deviceID = deviceID;
}
#Override
public void run() {
int i = 0;
try {
soundMeter.start();
soundRecorder.start(getFileNameString());
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
if(isKilled){
break;
}
if(soundMeter.getAmplitudeEMA() < 4.0){
i++;
if(i > 10){
break;
}
} else {
i = 0;
}
}
soundMeter.stop();
soundRecorder.stop();
EavesDrop.currentlyRecording = false;
}
public void kill(){
this.isKilled = true;
}
private String getFileNameString() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
return deviceID + "_" + sdf.format(new Date());
}
}
Now the IllegalStateException is thrown from the Recordinghandler - on the line soundMeter.start();.
Considering that this soundMeter object is basically not handled in a loop anymore, should eliminate the though that the while loop was the culprit. Is there something that I am missing? Could the problem be in having multiple MediaRecorders working at the same time? As you can see, now it is the SoundMeter, not the SoundRecorder which is throwing the exception. Actually - whichever start() call I place first in the RecordingHandler, throws the same IllegalStateException.
The question might be connected to Android: Two instances of Media recorder at same time, which unfortunately has no answers.
Any further help would be greatly appreciated!
Okay, it seems I cracked the problem. The problem seems to be in having multiple instances of MediaRecorder working at the same time. What I did, was that I now don't use separate classes for detection and recording, so that the recorder now does it's own detection.
At first I initiate the inital SoundMeter which listens until it gets input over level 4.0. Then I stop the initial SoundMeter and make a new SoundMeter (with different output directory), which starts recording and records until the levels have been below 4.0 for apprixamtely 10 seconds. Then the second SoundMeter is stopped and the background task can start the initial SoundMeter again.
Here is the code which solved my problem,
AsyncTask:
protected Object doInBackground(Object[] params) {
int i = 0;
soundMeter = new SoundMeter();
RecordingHandler recordingHandler = null;
try {
soundMeter.start("/dev/null");
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
if(isCancelled()){
soundMeter.stop();
if(currentlyRecording && recordingHandler != null){
recordingHandler.kill();
}
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("error", e.getMessage());
}
if(!currentlyRecording && soundMeter.getAmplitudeEMA() > 4.0){
soundMeter.stop();
recordingHandler = new RecordingHandler(deviceId);
currentlyRecording = true;
recordingHandler.run();
} else if(!currentlyRecording && !soundMeter.isRunning()){
try {
soundMeter.start("/dev/null");
} catch (IOException e) {
Log.e("error", e.getMessage());
}
}
}
return null;
}
}
And the RecordingHandler.run():
#Override
public void run() {
int i = 0;
try {
soundMeter.start(getFileNameString());
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("error", e.getMessage());
}
if(isKilled){
break;
}
if(soundMeter.getAmplitudeEMA() < 4.0){
i++;
if(i > 10){
break;
}
} else {
i = 0;
}
}
soundMeter.stop();
EavesDrop.currentlyRecording = false;
}
The documentation at http://developer.android.com/reference/android/media/MediaRecorder.html , under the release() method documentation, it talks about multiple instances not being suppported on some devices. So it might be a specific device related problem.