[Q] Android BLE Scan Blocks UI Threads - Java for Android App Development

I am working on an Andriod project with Bluetooth LE. While BLE thread was scanning, this thread blocks other threads such as HTTP request and MediaPlayer . Http request is going to timeout or when i play music with meidplayer in app then app is freezing. I get this problem on thees android devices,Samsung Glaxy Tab SM-T700 and Samsung Galaxy TAB SM-T800. But i do not get this problem on Samsung Galaxy TAB SM-T520 device and any android phones.
Code:
BLE Scan Algorithm ` private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
final byte[] scanRecord) {
ac.runOnUiThread(new Runnable() {
@Override
public void run() {
final BluetoothLeDevice deviceLe = new BluetoothLeDevice(
device, rssi, scanRecord, System
.currentTimeMillis());
// mDevices.add(deviceLe);
String rssiString = ac.getString(R.string.formatter_db,
String.valueOf(deviceLe.getRssi()));
if (tempDevice == null) {
tempDevice = deviceLe;
} else {
if (deviceLe.getRunningAverageRssi() > tempDevice
.getRunningAverageRssi()) {
IBeaconDevice newBeacon = new IBeaconDevice(
deviceLe);
IBeaconDevice bestDevice = new IBeaconDevice(
tempDevice);
if (newBeacon.getMajor() != bestDevice.getMajor()
|| newBeacon.getMinor() != bestDevice
.getMinor()) {
tempDevice = deviceLe;
}
}
}
}
// }
});
}
};` Music Play Algorithm . Mediaplayer is initialed before this code ` public void PlayPause() {
Log.e("Çalan", UrlSes);
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.reset();
}
try {
mediaPlayer.setDataSource(UrlSes); // setup song from
// http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3
// URL to mediaplayer data
// source
mediaPlayer.prepare(); // you must call this method after setup the
// datasource in setDataSource method. After
// calling prepare() the instance of
// MediaPlayer starts load data from URL to
// internal buffer.
} catch (Exception e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the
// song
// length in
// milliseconds
// from URL
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
imgPlay.setImageResource(R.drawable.footer_pause);
} else {
mediaPlayer.pause();
imgPlay.setImageResource(R.drawable.footer_play);
}
primarySeekBarProgressUpdater();
}` app freeze on mediplayer.prepare() I use mediplayer.prepareasync() but not plyaed . my web Request code `public JSONObject getJSONInfo(String functionName) {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
HttpResponse response;
JSONObject json = null;
JSONObject send = new JSONObject();
try {
HttpPost post = new HttpPost(
""+url);
send.put("", variable1);
send.put("", variable1);
send.put("", variable2);
send.put("", variable1);
StringEntity se = new StringEntity(send.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
Log.e("test", send.toString());
post.setEntity(se);
response = client.execute(post);
if (response.getStatusLine().getStatusCode() == 200) {
json = new JSONObject(
EntityUtils.toString(response.getEntity()));
}
} catch (Exception e) {
e.printStackTrace();
}
return json;
}
I'think This problem not about code or algorithm. Maybe about setting in device. Please help.

Same problem
Hi, did you find any solution for this ? I stucked on same problem and cant find how to solve this problem. :crying:
Thaks a lot for any advice.

Related

[Q] Shoutcast ICY to Http (Eclair compatible)

Hi.
I'm currently working on a wakeup-app (alarm) that plays your favorite radio-station via shoutcast-stream.
It looked really easy:
Code:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(PATH_TO_FILE);
mp.prepare();
mp.start();
Then I found out Eclair doesn't support shoutcast's ICY protocol. Grmbl.
So for 2.1 (and earlier versions) it is required to handle the shoutcast-stream seperatly and pass it to MediaPlayer via http.
I even found an example:
http://code.google.com/p/npr-android-app/source/browse/trunk/Npr/src/org/npr/android/news/StreamProxy.java
Problem is that it's all a bit too advanced for me, so I was wondering if anyone has a really simple example of how to do this?
Something like:
"Add 'this file' to your project (where 'this file' would be a class similarly to StreamProxy) and then add this to your application:"
Code:
StreamProxy sp = new StreamProxy();
sp.setDataSource( SHOUTCAST_URL );
MediaPlayer mp = new MediaPlayer();
mp.setDataSource( sp.getProxyUrl );
mp.prepare();
mp.start();
(Pardon my english
fixed!
Will post how I did it soon.
Here's the app:
http://android.rejh.nl/fmalarm
Just got reminded by someone that I never posted the solution. Here goes:
Code:
// Streamurl
String streamUrl = "[Path-to-audio-stream-or-file]";
// Prepare Proxy (for Android 2.1 en lower (sdk<8))
sdkVersion = 0;
try { sdkVersion = Integer.parseInt(Build.VERSION.SDK); } // Note: Build.VERSION.SDK is deprecated..
catch (NumberFormatException e) {}
if (sdkVersion<8) {
if (proxy==null) {
try {
proxy = new StreamProxy();
proxy.init();
proxy.start();
streamUrl = String.format("http://127.0.0.1:%d/%s", proxy.getPort(), url);
} catch(IllegalStateException e) { Log.e(LOGTAG," -> IllStateException: "+e, e); }
}
}
// Create mediaplayer and set stream (proxied if needed)
mp = new MediaPlayer();
mp.setDataSource(streamUrl);
UPDATE!! Forgot the StreamProxy code
Code:
// Copyright 2010 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Minor changes by REJH Gadellaa 2010/2011
package org.npr.android.news;
import android.util.Log;
import org.apache.http.Header;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseFactory;
import org.apache.http.ParseException;
import org.apache.http.ProtocolVersion;
import org.apache.http.RequestLine;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.conn.OperatedClientConnection;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.DefaultClientConnection;
import org.apache.http.impl.conn.DefaultClientConnectionOperator;
import org.apache.http.impl.conn.DefaultResponseParser;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.io.HttpMessageParser;
import org.apache.http.io.SessionInputBuffer;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicLineParser;
import org.apache.http.message.ParserCursor;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.CharArrayBuffer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.StringTokenizer;
public class StreamProxy implements Runnable {
private static final String LOG_TAG = "FMA2Proxy";
private int port = 5050;
public int getPort() {
return port;
}
private boolean isRunning = true;
private ServerSocket socket;
private Thread thread;
public void init() {
try {
socket = new ServerSocket(port, 0, InetAddress.getByAddress(new byte[] {127,0,0,1}));
socket.setSoTimeout(5000);
port = socket.getLocalPort();
Log.d(LOG_TAG, "port " + port + " obtained");
} catch (UnknownHostException e) {
Log.e(LOG_TAG, "Error initializing server", e);
} catch (IOException e) {
Log.e(LOG_TAG, "Error initializing server", e);
}
}
public void start() {
if (socket == null) {
throw new IllegalStateException("Cannot start proxy; it has not been initialized.");
}
thread = new Thread(this);
thread.start();
}
public void stop() {
isRunning = false;
if (thread == null) {
throw new IllegalStateException("Cannot stop proxy; it has not been started.");
}
if (socket!=null) { try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
thread.interrupt();
try {
thread.join(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// @Override
public void run() {
Log.d(LOG_TAG, "running");
while (isRunning) {
try {
Socket client = socket.accept();
if (client == null) {
continue;
}
Log.d(LOG_TAG, "client connected");
HttpRequest request = readRequest(client);
processRequest(request, client);
} catch (SocketTimeoutException e) {
// Do nothing
} catch (IOException e) {
Log.e(LOG_TAG, "Error connecting to client", e);
}
}
Log.d(LOG_TAG, "Proxy interrupted. Shutting down.");
}
private HttpRequest readRequest(Socket client) {
HttpRequest request = null;
InputStream is;
String firstLine;
try {
is = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
firstLine = reader.readLine();
} catch (IOException e) {
Log.e(LOG_TAG, "Error parsing request", e);
return request;
}
if (firstLine == null) {
Log.i(LOG_TAG, "Proxy client closed connection without a request.");
return request;
}
StringTokenizer st = new StringTokenizer(firstLine);
String method = st.nextToken();
String uri = st.nextToken();
Log.d(LOG_TAG, uri);
String realUri = uri.substring(1);
Log.d(LOG_TAG, realUri);
request = new BasicHttpRequest(method, realUri);
return request;
}
private HttpResponse download(String url) {
DefaultHttpClient seed = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
registry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
SingleClientConnManager mgr = new MyClientConnManager(seed.getParams(),
registry);
DefaultHttpClient http = new DefaultHttpClient(mgr, seed.getParams());
HttpGet method = new HttpGet(url);
HttpResponse response = null;
try {
Log.d(LOG_TAG, "starting download");
response = http.execute(method);
Log.d(LOG_TAG, "downloaded");
} catch (ClientProtocolException e) {
Log.e(LOG_TAG, "Error downloading", e);
} catch (IOException e) {
Log.e(LOG_TAG, "Error downloading", e);
}
return response;
}
private void processRequest(HttpRequest request, Socket client)
throws IllegalStateException, IOException {
if (request == null) {
return;
}
Log.d(LOG_TAG, "processing");
String url = request.getRequestLine().getUri();
HttpResponse realResponse = download(url);
if (realResponse == null) {
return;
}
Log.d(LOG_TAG, "downloading...");
InputStream data = realResponse.getEntity().getContent();
StatusLine line = realResponse.getStatusLine();
HttpResponse response = new BasicHttpResponse(line);
response.setHeaders(realResponse.getAllHeaders());
Log.d(LOG_TAG, "reading headers");
StringBuilder httpString = new StringBuilder();
httpString.append(response.getStatusLine().toString());
httpString.append("\n");
for (Header h : response.getAllHeaders()) {
httpString.append(h.getName()).append(": ").append(h.getValue()).append(
"\n");
}
httpString.append("\n");
Log.d(LOG_TAG, "headers done");
try {
byte[] buffer = httpString.toString().getBytes();
int readBytes = -1;
Log.d(LOG_TAG, "writing to client");
client.getOutputStream().write(buffer, 0, buffer.length);
// Start streaming content.
byte[] buff = new byte[1024 * 50];
while (isRunning && (readBytes = data.read(buff, 0, buff.length)) != -1) {
client.getOutputStream().write(buff, 0, readBytes);
}
} catch (Exception e) {
Log.e("", e.getMessage(), e);
} finally {
if (data != null) {
data.close();
}
client.close();
}
}
private class IcyLineParser extends BasicLineParser {
private static final String ICY_PROTOCOL_NAME = "ICY";
private IcyLineParser() {
super();
}
@Override
public boolean hasProtocolVersion(CharArrayBuffer buffer,
ParserCursor cursor) {
boolean superFound = super.hasProtocolVersion(buffer, cursor);
if (superFound) {
return true;
}
int index = cursor.getPos();
final int protolength = ICY_PROTOCOL_NAME.length();
if (buffer.length() < protolength)
return false; // not long enough for "HTTP/1.1"
if (index < 0) {
// end of line, no tolerance for trailing whitespace
// this works only for single-digit major and minor version
index = buffer.length() - protolength;
} else if (index == 0) {
// beginning of line, tolerate leading whitespace
while ((index < buffer.length()) &&
HTTP.isWhitespace(buffer.charAt(index))) {
index++;
}
} // else within line, don't tolerate whitespace
if (index + protolength > buffer.length())
return false;
return buffer.substring(index, index + protolength).equals(ICY_PROTOCOL_NAME);
}
@Override
public Header parseHeader(CharArrayBuffer buffer) throws ParseException {
return super.parseHeader(buffer);
}
@Override
public ProtocolVersion parseProtocolVersion(CharArrayBuffer buffer,
ParserCursor cursor) throws ParseException {
if (buffer == null) {
throw new IllegalArgumentException("Char array buffer may not be null");
}
if (cursor == null) {
throw new IllegalArgumentException("Parser cursor may not be null");
}
final int protolength = ICY_PROTOCOL_NAME.length();
int indexFrom = cursor.getPos();
int indexTo = cursor.getUpperBound();
skipWhitespace(buffer, cursor);
int i = cursor.getPos();
// long enough for "HTTP/1.1"?
if (i + protolength + 4 > indexTo) {
throw new ParseException
("Not a valid protocol version: " +
buffer.substring(indexFrom, indexTo));
}
// check the protocol name and slash
if (!buffer.substring(i, i + protolength).equals(ICY_PROTOCOL_NAME)) {
return super.parseProtocolVersion(buffer, cursor);
}
cursor.updatePos(i + protolength);
return createProtocolVersion(1, 0);
}
@Override
public RequestLine parseRequestLine(CharArrayBuffer buffer,
ParserCursor cursor) throws ParseException {
return super.parseRequestLine(buffer, cursor);
}
@Override
public StatusLine parseStatusLine(CharArrayBuffer buffer,
ParserCursor cursor) throws ParseException {
StatusLine superLine = super.parseStatusLine(buffer, cursor);
return superLine;
}
}
class MyClientConnection extends DefaultClientConnection {
@Override
protected HttpMessageParser createResponseParser(
final SessionInputBuffer buffer,
final HttpResponseFactory responseFactory, final HttpParams params) {
return new DefaultResponseParser(buffer, new IcyLineParser(),
responseFactory, params);
}
}
class MyClientConnectionOperator extends DefaultClientConnectionOperator {
public MyClientConnectionOperator(final SchemeRegistry sr) {
super(sr);
}
@Override
public OperatedClientConnection createConnection() {
return new MyClientConnection();
}
}
class MyClientConnManager extends SingleClientConnManager {
private MyClientConnManager(HttpParams params, SchemeRegistry schreg) {
super(params, schreg);
}
@Override
protected ClientConnectionOperator createConnectionOperator(
final SchemeRegistry sr) {
return new MyClientConnectionOperator(sr);
}
}
}

Android ICS SSL Authentication Help

Im trying to build an RSS feed reader that needs to do some client side SSL authentication.
Ive got, or at least think i have, the certificate and now cannot figure out how to setup a ssl tunnel to send the certificate to the server to authenticate.
here is what i have so far:
public class Authenticator extends Activity {
PrivateKey privateKey = null;
String SavedAlias = "";
private static final String TAG = "AUTHENTICATOR.CLASS";
final HttpParams httpParams = new BasicHttpParams();
private KeyStore mKeyStore = KeyStore.getInstance();
public Handler mHandler = new Handler(Looper.getMainLooper());
public void run()
{
mHandler.post(new Runnable() {
public void run() {
new AliasLoader().execute();
}
});
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getCertificates("TEST");
}
public class AliasLoader extends AsyncTask<Void, Void, X509Certificate[]>
{
X509Certificate[] chain = null;
@Override protected X509Certificate[] doInBackground(Void... params) {
android.os.Debug.waitForDebugger();
if(!SavedAlias.isEmpty())
{
try {
chain = KeyChain.getCertificateChain(getApplicationContext(),SavedAlias);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
else
{
this.cancel(true);
}
return chain;
}
@Override
protected void onPostExecute(X509Certificate[] chain)
{
if(chain != null)
{
Toast.makeText(getApplicationContext(), "YAY, Certificate is not empty", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "Certificate is Empty", Toast.LENGTH_LONG).show();
}
/*
if (privateKey != null) {
Signature signature = null;
try {
signature = Signature.getInstance("SHA1withRSA");
} catch (NoSuchAlgorithmException e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
try {
signature.initSign(privateKey);
} catch (InvalidKeyException e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
}
*/
}
}
public void getCertificates(String Host)
{
KeyChainAliasCallback callBack = new KeyChainAliasCallback() {
@Override
public void alias(String alias) {
if (alias != null)
{
Looper.prepare();
saveAlias(alias);
run();
Looper.loop();
}
}
};
KeyChain.choosePrivateKeyAlias(this, callBack,
new String[] {"RSA", "DSA"}, // List of acceptable key types. null for any
null, // issuer, null for any
null, // host name of server requesting the cert, null if unavailable
443, // port of server requesting the cert, -1 if unavailable
null); // alias to preselect, null if unavailable
}
public void saveAlias(String alias)
{
SavedAlias = alias;
}
}
Any help on how to do this would be greatly appreciated as i have never done any authentication before and i have found it difficult to find anything on this topic for android 4.0 as 4.0 seems to be different in implementation then the older versions.

Retrieving cpu frequency

Hi everyone.
I want to retrieve the current cpu frequency in my app but I don't seem to be right.
In my code I want to read the "scaling_cpu_freq" file from internal storage.
This is the code:
Code:
private String ReadCPUMhz() {
String cpuMaxFreq = "";
int cur = 0;
try {
[user=1299008]@supp[/user]ressWarnings("resource")
BufferedReader maxi = new BufferedReader(new FileReader(new File("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq")));
try{
cpuMaxFreq = maxi.readLine();
cur = Integer.parseInt(cpuMaxFreq);
cur = cur/1000;
} catch (Exception ex){
ex.printStackTrace();
}
} catch (FileNotFoundException f) {
f.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return String.valueOf(cur);
}
The problem is that the method only returns 0, which is the initial value of the int "cur".
Can anybody help me?
Thanks in advance.
Here's the code I use:
Declare this class in your Activity
Code:
// Read current frequency from /sys in a separate thread
// This class assumes your TextView is declared and referenced in the OnCreate of the class this one is declared in
// And its variable name is mCurCpuFreq
protected class CurCPUThread extends Thread {
private static final String CURRENT_CPU = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq";
private boolean mInterrupt = false;
public void interrupt() {
mInterrupt = true;
}
[user=439709]@override[/user]
public void run() {
try {
while (!mInterrupt) {
sleep(400);
final String curFreq = readOneLine(CURRENT_CPU);
mCurCPUHandler.sendMessage(mCurCPUHandler.obtainMessage(0,
curFreq));
}
} catch (InterruptedException e) {
return;
}
}
}
// Update real-time current frequency & stats in a separate thread
protected static Handler mCurCPUHandler = new Handler() {
public void handleMessage(Message msg) {
mCurFreq.setText(toMHz((String) msg.obj));
final int p = Integer.parseInt((String) msg.obj);
new Thread(new Runnable() {
public void run() {
// Here I update a real-time graph of the current freq
}
}
}).start();
}
};
Helper methods used :
Code:
// Convert raw collected values to formatted MhZ
private static String toMHz(String mhzString) {
if (Integer.valueOf(mhzString) != null)
return String.valueOf(Integer.valueOf(mhzString) / 1000) + " MHz";
else
return "NaN";
}
// Iterate through the /sys file
public static String readOneLine(String fname) {
BufferedReader br;
String line = null;
try {
br = new BufferedReader(new FileReader(fname), 512);
try {
line = br.readLine();
} finally {
br.close();
}
} catch (Exception e) {
Log.e(TAG, "IO Exception when reading sys file", e);
// attempt to do magic!
return readFileViaShell(fname, true);
}
return line;
}
// Backup method if the above one fails
public static String readFileViaShell(String filePath, boolean useSu) {
CommandResult cr = null;
if (useSu) {
cr = new CMDProcessor().runSuCommand("cat " + filePath);
} else {
cr = new CMDProcessor().runShellCommand("cat " + filePath);
}
if (cr.success())
return cr.getStdout();
return null;
}
CMDProcessor.java and its dependencies attached to this post

[Q] Can I register a listener on process state?

I'm an experienced developer but new to Android development. I have an app that runs some native binaries, and I provide a status indicator to show when the native process is running and when it's not. Currently I poll the device to figure this out, using the ActivityManager API to determine if specific processes are running or not.
I'm hoping there is some way to register a listener on process state changes, so I can get notified when my process starts or stops. I looked through the API, and there doesn't seem to be such a thing. Does anyone know how I can keep track of process start and stop other than polling via ActivityManager?
MidnightJava said:
I'm an experienced developer but new to Android development. I have an app that runs some native binaries, and I provide a status indicator to show when the native process is running and when it's not. Currently I poll the device to figure this out, using the ActivityManager API to determine if specific processes are running or not.
I'm hoping there is some way to register a listener on process state changes, so I can get notified when my process starts or stops. I looked through the API, and there doesn't seem to be such a thing. Does anyone know how I can keep track of process start and stop other than polling via ActivityManager?
Click to expand...
Click to collapse
Afaik there's no way to accomplish that other than your way or being system/root app. See this similar question here for reference.
Can you show how you start the process?
EmptinessFiller said:
Can you show how you start the process?
Click to expand...
Click to collapse
Sure. Here's the class that manages starting, stopping, and statusing (running or not) the binary executable. In this case, it's the omniNames service of the omni ORB (CORBA broker).
Code:
public class RHManager {
private TimerTask task = new TimerTask() {
@Override
public void run() {
if (RHManager.this.listener != null) {
listener.running(isOmniNamesRunning());
}
}
};
private IStatusListener listener;
public RHManager() {
}
public void startOmniNames() {
final Exec exec = new Exec();
final String[] args = new String[]
{RhMgrConstants.INSTALL_LOCATION_OMNI_NAMES_SCRIPTS + "/" + RhMgrConstants.OMNI_NAMES_SCRIPT_FILE,
"start"};
final String[] env = new String[] {"LD_LIBRARY_PATH=/sdcard/data/com.axiosengineering.rhmanager/omniORB/lib"};
Thread t = new Thread() {
public void run() {
try {
int res = exec.doExec(args, env);
logMsg("omniNames start return code " + res);
} catch (IOException e) {
logMsg("Failed to start omniNames");
e.printStackTrace();
}
String std = exec.getOutResult();
logMsg("omniNames start: std out==> " + std );
String err = exec.getErrResult();
logMsg("omniNames start: err out==> " + err );
};
};
t.start();
logMsg("omniNames started");
}
private boolean isOmniNamesRunning() {
String pid_s = getOmniNamesPid();
Integer pid = null;
if (pid_s != null) {
try {
pid = Integer.parseInt(pid_s);
} catch (NumberFormatException e) {
return false;
}
}
if (pid != null) {
RunningAppProcessInfo activityMgr = new ActivityManager.RunningAppProcessInfo("omniNames", pid, null);
return activityMgr.processName != null ;
}
return false;
}
public void stopOmniNames() {
String pid = getOmniNamesPid();
android.os.Process.killProcess(Integer.parseInt(pid));
android.os.Process.sendSignal(Integer.parseInt(pid), android.os.Process.SIGNAL_KILL);
}
private String getOmniNamesPid() {
Exec exec = new Exec();
final String[] args = new String[]
{RhMgrConstants.INSTALL_LOCATION_OMNI_NAMES_SCRIPTS + "/" + RhMgrConstants.OMNI_NAMES_SCRIPT_FILE,
"pid"};
String pid = "";
try {
int res = exec.doExec(args, null);
logMsg("oniNames pid return code: " + res);
} catch (IOException e) {
logMsg("Failed to start omniNames");
e.printStackTrace();
return pid;
}
String std = exec.getOutResult();
logMsg("omniNames pid: std out ==> " + std);
String err = exec.getErrResult();
logMsg("omniNames pid: err out ==> " + err);
String[] parts = std.split("\\s+");
if (parts.length >= 2) {
pid = parts[1];
}
return pid;
}
//monitor omniNames status and report status periodically to an IStatusListener
public void startMonitorProcess(IStatusListener listener, String string) {
this.listener = listener;
Timer t = new Timer();
t.schedule(task, 0, 1000);
}
private void logMsg(String msg) {
if (RhMgrConstants.DEBUG) {
System.err.println(msg);
}
}
}
Here's the Exec class that handles invocation of Runtime#exec(), consumes std and err out, and reports those and process return status to the caller.
Code:
public class Exec {
private String outResult;
private String errResult;
private Process process;
private boolean failed = false;
StreamReader outReader;
StreamReader errReader;
public int doExec(String[] cmd, String[] envp) throws IOException{
Timer t = null;
try {
process = Runtime.getRuntime().exec(cmd, envp);
outReader = new StreamReader(process.getInputStream());
outReader.setPriority(10);
errReader = new StreamReader(process.getErrorStream());
outReader.start();
errReader.start();
t = new Timer();
t.schedule(task, 10000);
int status = process.waitFor();
outReader.join();
errReader.join();
StringWriter outWriter = outReader.getResult();
outResult = outWriter.toString();
outWriter.close();
StringWriter errWriter = errReader.getResult();
errResult = errWriter.toString();
errWriter.close();
return (failed ? -1: status);
} catch (InterruptedException e) {
return -1;
} finally {
if (t != null) {
t.cancel();
}
}
}
public int doExec(String[] cmd) throws IOException{
return doExec(cmd, null);
}
public String getOutResult(){
return outResult;
}
public String getErrResult(){
return errResult;
}
private static class StreamReader extends Thread {
private InputStream is;
private StringWriter sw;
StreamReader(InputStream is) {
this.is = is;
sw = new StringWriter(30000);
}
public void run() {
try {
int c;
while ((c = is.read()) != -1){
sw.write(c);
}
}
catch (IOException e) { ; }
}
StringWriter getResult() {
try {
is.close();
} catch (IOException e) {
System.err.println("Unable to close input stream in StreamReader");
}
return sw;
}
}
private TimerTask task = new TimerTask() {
@Override
public void run() {
failed = true;
process.destroy();
}
};
}
Here's the script that startOminNames() invokes. It's the shell script installed with omniORB with functions other than start and get_pid removed, since those are handled by Android classes. You can invoke any executable in place of the script, or wrap your executable in a script.
Code:
#
# omniNames init file for starting up the OMNI Naming service
#
# chkconfig: - 20 80
# description: Starts and stops the OMNI Naming service
#
exec="/sdcard/data/com.axiosengineering.rhmanager/omniORB/bin/omniNames"
prog="omniNames"
logdir="/sdcard/data/com.axiosengineering.rhmanager/omniORB/logs"
logfile="/sdcard/data/com.axiosengineering.rhmanager/omniORB/logs/omninames-localhost.err.log"
options=" -start -always -logdir $logdir -errlog $logfile"
start() {
#[ -x $exec ] || exit 5
echo -n $"Starting $prog: "
$exec $options
}
get_pid() {
ps | grep omniNames
}
case "$1" in
start)
start && exit 0
$1
;;
pid)
get_pid
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?
And here's the IStatusListener interface
Code:
public interface IStatusListener {
public void running(boolean running);
}
Runtime.exec() has some pitfalls. See this helpful Runtime.exec tutorial for a nice explanation.
And you may also want to check out this post on loading native binaries in Android.

Camera2 focus state during preview

Hi,
I have built a small notepad+barcodescanner app. Not it works, but the performance is low, as it processes all frames. It would be good if it would process only frams which are captured when the focus settled.
The app uses Camera2 PreviewBulder and CaptureRequestBuilder / RepeatingRequest, but i only found ways to get focus state during a Capturesession. (Capture is not used in this app, only getting frames from preview).
Does anyone how to process the focus state if one uses a Preview...?
Thanks for any help
Corresponding code part:
private final CameraDevice.StateCallback stateCallback = new
CameraDevice.StateCallback() {
@override
public void onOpened(CameraDevice camera) {
//This is called when the camera is open
// Log.e(TAG, "onOpened");
cameraDevice = camera;
createCameraPreview();
}
@override
public void onDisconnected(CameraDevice camera) {
cameraDevice.close();
}
@override
public void onError(CameraDevice camera, int error) {
cameraDevice.close();
cameraDevice = null;
}
};
final CameraCaptureSession.CaptureCallback captureCallbackListener = new CameraCaptureSession.CaptureCallback() {
@override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
// makeText(MainActivity.this, "Saved:" + file, LENGTH_SHORT).show();
createCameraPreview();
}
};
protected void startBackgroundThread() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
protected void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
protected void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(),
imageDimension.getHeight());
Surface surface = new Surface(texture);
CameraManager manager;
manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
String camerId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(camerId);
boolean aelockavailable = characteristics.get(CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE);
}catch (Exception e)
{
}
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, captureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
//captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, captureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface),
new CameraCaptureSession.StateCallback() {
@override
public void onConfigured(@NonNull CameraCaptureSession
cameraCaptureSession) {
//The camera is already closed
if (null == cameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
@override
public void onConfigureFailed(@NonNull
CameraCaptureSession cameraCaptureSession) {
//makeText(MainActivity.this, "Configuration change", LENGTH_SHORT).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
void openCamera() {
CameraManager manager = (CameraManager)
getSystemService(Context.CAMERA_SERVICE);
//Log.e(TAG, "is camera open");
try {
cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics =
manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map =
characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
// Add permission for camera and let user grant the permission
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId, stateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
//Log.e(TAG, "openCamera X");
}
void updatePreview() {
if (null == cameraDevice) {
//Log.e(TAG, "updatePreview error, return");
}
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, captureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
//captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
if (flashchanged) {flashchanged=false; if (lamp && autoflash) {captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);} else {captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);} }
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),
null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void closeCamera() {
if (null != cameraDevice) {
cameraDevice.close();
cameraDevice = null;
}
if (null != imageReader) {
imageReader.close();
imageReader = null;
}
}

Categories

Resources