Very old project I have 'inherited', Apache 2.2.0 and apparently has never 'worked right'.
The process seems to 'lock up' occasionally and never completes. If the process is killed, files moved back to inbound, and restarted it seems to work. So it's a weird intermittent problem.
I believe the issue may be due to a custom RoutePolicy implementation;
package com.company.integration.management;
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Route;
import org.apache.camel.SuspendableService;
import org.apache.camel.component.seda.SedaEndpoint;
import org.apache.camel.impl.ThrottlingInflightRoutePolicy;
import org.apache.log4j.Logger;
public class ParserInflightRoutePolicy extends ThrottlingInflightRoutePolicy {
private static Route fileRoute;
private static final int MAX_FILES_INFLIGHT = 3;
private static final int MSG_HIGH_WATERMARK = 100;
private static final int MSG_LOW_WATERMARK = 25;
private Logger logger = Logger.getLogger(getClass());
#Override
public void onExchangeBegin(Route route, Exchange exchange) {
int sedaMessagesInflight = 0;
sedaMessagesInflight = sedaQueueSize(route);
if (route.getId().equalsIgnoreCase("initialRoute")) {
fileRoute = route;
try {
if ((sedaQueueSize(route, "seda://parser") >= MAX_FILES_INFLIGHT) || (sedaMessagesInflight >= MSG_HIGH_WATERMARK)) {
if ( ! ((SuspendableService)fileRoute.getConsumer()).isSuspended() ) {
logger.error("FLOW CONTROL: stop file component");
((SuspendableService)fileRoute.getConsumer()).suspend();
}
}
}
catch (Exception ex) {
logger.error("Error stopping route", ex);
}
}
if (route.getId().equalsIgnoreCase("pricingRoute") || route.getId().equalsIgnoreCase("persistenceRoute")) {
try {
if ((sedaQueueSize(route, "seda://parser") == 0) && (sedaMessagesInflight <= MSG_LOW_WATERMARK)) {
if ( ((SuspendableService)fileRoute.getConsumer()).isSuspended() ) {
logger.error("FLOW CONTROL: start file component");
((SuspendableService)fileRoute.getConsumer()).resume();
}
}
}
catch (Exception ex) {
logger.error("Error starting route", ex);
}
}
}
int sedaQueueSize(Route route) {
int sedaMessagesInflight = 0;
CamelContext camelContext = route.getRouteContext().getCamelContext();
for (Route rte : camelContext.getRoutes()) {
Endpoint endpoint = rte.getEndpoint();
if (endpoint instanceof SedaEndpoint) {
SedaEndpoint seda = (SedaEndpoint)endpoint;
if (seda.getQueue().size() > 0) {
sedaMessagesInflight += seda.getQueue().size();
}
}
}
logger.debug("SEDA messages inflight [" + sedaMessagesInflight + "]");
return sedaMessagesInflight;
}
int sedaQueueSize(Route route, String endPointUri) {
CamelContext camelContext = route.getRouteContext().getCamelContext();
Endpoint endpoint = camelContext.getEndpoint(endPointUri);
if (endpoint instanceof SedaEndpoint) {
return ((SedaEndpoint) endpoint).getQueue().size();
}
return 0;
}
#Override
public void onExchangeDone(Route route, Exchange exchange) {
;
}
}
Notice that this code does not appear to be threadsafe - no locking mechanism as implemented in ThottlingInflightRoutePolicy. Could this be causing the intermittent issue?
Related
I have client like this :
import org.basex.api.client.ClientSession;
#Slf4j
#Component(value = "baseXAircrewClient")
#DependsOn(value = "baseXAircrewServer")
public class BaseXAircrewClient {
#Value("${basex.server.host}")
private String basexServerHost;
#Value("${basex.server.port}")
private int basexServerPort;
#Value("${basex.admin.password}")
private String basexAdminPassword;
#Getter
private ClientSession session;
#PostConstruct
private void createClient() throws IOException {
log.info("##### Creating BaseX client session {}", basexServerPort);
this.session = new ClientSession(basexServerHost, basexServerPort, UserText.ADMIN, basexAdminPassword);
}
}
It is a singleton injected in a service which run mulitple queries like this :
Query query = client.getSession().query(finalQuery);
return query.execute();
All threads query and share the same session.
With a single thread all is fine but with multiple thread I get some random (and weird) error, like the result of a query to as a result of another.
I feel that I should put a synchronized(){} arround query.execute() or open and close session for each query, or create a pool of session.
But I don't find any documentation how the use the session in parrallel.
Is this implementation fine for multithreading (and my issue is comming from something else) or should I do it differently ?
I ended creating a simple pool by adding removing the client from a ArrayBlockingQueue and it is working nicely :
#PostConstruct
private void createClient() throws IOException {
log.info("##### Creating BaseX client session {}", basexServerPort);
final int poolSize = 5;
this.resources = new ArrayBlockingQueue < ClientSession > (poolSize) {
{
for (int i = 0; i < poolSize; i++) {
add(initClient());
}
}
};
}
private ClientSession initClient() throws IOException {
ClientSession clientSession = new ClientSession(basexServerHost, basexServerPort, UserText.ADMIN, basexAdminPassword);
return clientSession;
}
public Query query(String finalQuery) throws IOException {
ClientSession clientSession = null;
try {
clientSession = resources.take();
Query result = clientSession.query(finalQuery);
return result;
} catch (InterruptedException e) {
log.error("Error during query execution: " + e.getMessage(), e);
} finally {
if (clientSession != null) {
try {
resources.put(clientSession);
} catch (InterruptedException e) {
log.error("Error adding to pool : " + e.getMessage(), e);
}
}
}
return null;
}
package com.email.test;
import java.util.Arrays;
import java.util.Properties;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.FlagTerm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class SampleEmailReader {
public static final int SUCCESS = 0;
public static final int FAILURE = -1;
private transient static final Logger logger = LoggerFactory.getLogger(SampleEmailReader.class);
public SampleEmailReader() {
}
public void processEmailAttachements() {
try {
logger.info("Started processEmailAttachements ");
Properties emailProperties = new Properties();
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
emailProperties.setProperty("mail.imaps.socketFactory.class", SSL_FACTORY);
emailProperties.setProperty("mail.imaps.socketFactory.fallback", "false");
emailProperties.setProperty("mail.imaps.port", "993");
emailProperties.setProperty("mail.imaps.socketFactory.port", "993");
emailProperties.setProperty("mail.imaps.auth", "true");
emailProperties.setProperty("mail.imaps.host", "outlook.office365.com");
emailProperties.setProperty("mail.imaps.auth.plain.disable", "true");
emailProperties.setProperty("mail.imaps.auth.gssapi.disable", "true");
emailProperties.setProperty("mail.imaps.auth.ntlm.disable", "true");
emailProperties.setProperty("mail.imaps.ssl.enable", "true");
Session session = Session.getInstance(emailProperties,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("test#outlook.com", "password#2016");
}
});
Store store = session.getStore("imaps");
store.connect();
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
logger.info("Inbox MessageCount-->" + inbox.getMessageCount());
Message messages[] = inbox.search(new FlagTerm(
new Flags(Flag.SEEN), false));
logger.info("Number of UnRead Mails = " + messages.length);
for (Message inboxMessage : messages) {
int status = processMessageBody(inboxMessage);
if (status == SUCCESS) {
inboxMessage.setFlag(Flag.SEEN, true);
} else {
inboxMessage.setFlag(Flag.SEEN, false);
}
}
inbox.close(true);
store.close();
} catch (Exception ex) {
ex.printStackTrace();
logger.error("Error in processEmailAttachements", ex);
}
}
private int processMessageBody(Message message) {
int status = FAILURE;
try {
logger.info("Started processMessageBody*******");
logger.info("Message Subject******" + message.getSubject());
logger.info("From Address *******"
+ Arrays.toString(message.getFrom()));
Object content = message.getContent();
if (content instanceof String) {
logger.error("Invalid Content Type.No need to process the Mail with Subject "
+ message.getSubject());
} else if (content instanceof Multipart) {
Multipart multiPart = (Multipart) content;
try {
for (int i = 0; i < multiPart.getCount(); i++) {
BodyPart bodyPart = multiPart.getBodyPart(i);
if (bodyPart.getDisposition() != null
&& bodyPart.getDisposition().equalsIgnoreCase(
Part.ATTACHMENT)
&& bodyPart.getFileName() != null) {
status = readExcel(bodyPart);
}
}
} catch (Exception e) {
e.printStackTrace();
logger.error("BatchException in procesMultiPart", e);
}
}
} catch (Exception e) {
e.printStackTrace();
logger.error("Exception in processMessageBody", e);
}
return status;
}
public abstract int readExcel(BodyPart bodyPart);
}
Executing
package EmailTable;
import javax.mail.BodyPart;
public class Email {
public static void main(String[] args) {
// TODO Auto-generated method stub
SampleEmailReader reader = new SampleEmailReader() {
#Override
public int readExcel(BodyPart bodyPart) {
// TODO Auto-generated method stub
return 0;
}
};
reader.processEmailAttachements();
}
}
Getting Autheticate Failed.. But username password is correct. and i am able to login outlook 365 with the username and password. ONLY difference I am seeing there is certitificate displayed on the browser.. Do I need to use any certificate to read the mail?
javax.mail.AuthenticationFailedException: LOGIN failed.
at com.sun.mail.imap.IMAPStore.protocolConnect
I'm trying to apply FusedLocation provider in cn1 through native interface(android). I've implemented ConnectionCallbacks and OnConnectionFailedListener interfaces. It generates methods like onConnected(), onConnectionSuspended() and onConnectionFailed() in native android, which are not working when app is built in cn1.
Moreover, lifecycle methods like onResume, onDestroy of FusedLocationImpl etc are also not working. In the coming days, I'm planning to create the fused GPS library for general purpose as well.
PS. There are no build errors and got no any other errors when debugged.
FusedLocationImpl.java
import com.codename1.impl.android.AndroidNativeUtil;
import android.os.Bundle;
import android.location.Location;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationAvailability;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationListener;
public class FusedLocationImpl implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
private LocationRequest mLocationRequest;
public boolean isSupported() {
return true;
}
public void getFusedLocationPermission() {
if (!com.codename1.impl.android.AndroidNativeUtil.checkForPermission(Manifest.permission.ACCESS_FINE_LOCATION, "Please allow location permission")) {
}
}
public void fusedLocation() {
if (checkPlayServices()) {
buildGoogleApiClient();
}
}
public void onConnected(Bundle bundle) { // not working...
Log.i("onConnected", "GoogleApiClient connected!");
createLocationRequest();
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Log.i("onConnected", " Location: " + mLastLocation);
}
protected void createLocationRequest() { // not working...
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationCallback() {
#Override
public void onLocationResult(final LocationResult locationResult) {
Log.i("onLocationResult",locationResult + "");
}
#Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
Log.i("onLocationAvailability", "onLocationAvailability: isLocationAvailable = " + locationAvailability.isLocationAvailable());
}
}, null);
}
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
public void onConnectionFailed(ConnectionResult result) {
Log.i("onConnectionFailed", "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
public void onPause() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (LocationListener) this);
mGoogleApiClient.disconnect();
}
}
public void onResume() {
checkPlayServices();
}
public void onStart() {
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
Log.i("onStart", "mGoogleApiClient.connect()");
}
}
public void onDestroy() {
Log.i("onDestory", "Service destroyed!");
mGoogleApiClient.disconnect();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(AndroidNativeUtil.getActivity());
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, AndroidNativeUtil.getActivity(),
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
AndroidNativeUtil.getActivity().finish();
}
return false;
}
return true;
}
protected synchronized void buildGoogleApiClient() {
Log.i("buildGoogleApiClient", "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(AndroidNativeUtil.getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
FusedLocation.java
public interface FusedLocation extends NativeInterface{
public void getFusedLocationPermission();
public void fusedLocation();
}
MyApplication.java
public void start() {
if (current != null) {
current.show();
return;
}
Form hi = new Form("Hi World", BoxLayout.y());
hi.show();
Button btn = new Button("ask for permission");
FusedLocation fl = (FusedLocation) NativeLookup.create(FusedLocation.class);
Button btn1 = new Button("fused network");
hi.add(btn1);
btn1.addActionListener(e->{
if (fl != null && fl.isSupported()) {
fl.getFusedLocationPermission();
fl.fusedLocation();
System.out.println("fusedLocation");
}
});
}
PS. permission for location (ACCESS_FINE_LOCATION) succeeds. The main issue I've got is onConnected() and other implemented methods are not called. Thankyou
cn1 Location manager: this is not giving quite a performance as the native fused location provider
public final void checkGPS() {
if (Display.getInstance().getLocationManager().isGPSDetectionSupported()) {
if (Display.getInstance().getLocationManager().isGPSEnabled()) {
InfiniteProgress ip = new InfiniteProgress();
final Dialog ipDlg = ip.showInifiniteBlocking();
//Cancel after 20 seconds
Location loc = LocationManager.getLocationManager().getCurrentLocationSync(20000);
ipDlg.dispose();
if (loc != null) {
lat = loc.getLatitude();
lng = loc.getLongitude();
Dialog.show("location", "lat: " + lat + " lon: " + lng, "ok", null);
} else {
Dialog.show("GPS error", "Your location could not be found, please try going outside for a better GPS signal", "Ok", null);
}
} else {
Dialog.show("GPS disabled", "AppName needs access to GPS. Please enable GPS", "Ok", null);
}
} else {
Dialog.show("Warning", "GPS is not supported in your device", "ok", null);
}
}
I'm not sure why you aren't using the location listener which uses fused location internally when play services is enabled (the default).
You asked for permissions in the XML but didn't use the Android 6+ permissions which need a different syntax. Again, if you just use the location API this is all seamless...
I am trying to use OKHTTP (version 2.4.0) along retrofit (1.9.0) on google app engine (1.9.22).
Here is the how i use it:
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setConnectTimeout(COMPOSER_MODULE_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(COMPOSER_MODULE_SOCKET_TIMEOUT, TimeUnit.SECONDS);
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setConverter(new JacksonConverter())
.setEndpoint(ENDPOINT_PATH)
.setClient(new OkClient(okHttpClient))
.build();
This throws the following error:
java.lang.NoClassDefFoundError: java.net.ProxySelector is a restricted class. Please see the Google App Engine developer's guide for more details.
at com.google.apphosting.runtime.security.shared.stub.java.net.ProxySelector.<clinit>(ProxySelector.java)
at com.squareup.okhttp.OkHttpClient.copyWithDefaults(OkHttpClient.java:614)
at com.squareup.okhttp.Call.<init>(Call.java:50)
at com.squareup.okhttp.OkHttpClient.newCall(OkHttpClient.java:595)
at retrofit.client.OkClient.execute(OkClient.java:53)
I gather from the error that "java.net.ProxySelector" is not white-listed for use on google appengine.
Question 1)
Is it possible to use OKHTTP (version 2.4.0) along retrofit (1.9.0) on google app engine (1.9.22)? i.e, is there a work around for this error
if not,
Question 2)
Are there any other way to:
(a) use async HTTP calls with google appengine (with URLFetchService, for instance) ?
(b) set connection and socket timeouts for the client used from (a) ?
The links i have come across via search:
(1) Retrofit timeout configuration for clients
(2) Google App Engine URL Fetch Java API
You can use HttpUrlConnection with Retrofit2 to use it in Google APP Engine
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.http.HttpServletResponse;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
public class RetrofitCall implements Call {
Request request;
RetrofitCall(Request request) {
this.request = request;
}
#Override
public Request request() {
return request;
}
#Override
public Response execute() throws IOException {
URL url = request.url().url();
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setRequestMethod(request.method());
Headers headers = request.headers();
if (headers != null) {
for (int i = 0; i < headers.size(); i++) {
String name = headers.name(i);
connection.setRequestProperty(name, headers.get(name));
}
}
if (request.body() != null) {
BufferedSink outbuf;
outbuf = Okio.buffer(Okio.sink(connection.getOutputStream()));
request.body().writeTo(outbuf);
outbuf.close();
}
connection.connect();
final BufferedSource source = Okio.buffer(Okio.source(connection.getInputStream()));
if (connection.getResponseCode() != HttpServletResponse.SC_OK) {
throw new IOException("Fail to call " + " :: " + source.readUtf8());
}
Response response = new Response.Builder()
.code(connection.getResponseCode())
.message(connection.getResponseMessage())
.request(request)
.protocol(Protocol.HTTP_1_1)
.body(new ResponseBody() {
#Override
public MediaType contentType() {
return MediaType.parse(connection.getContentType());
}
#Override
public long contentLength() {
return connection.getContentLengthLong();
}
#Override
public BufferedSource source() {
return source;
}
})
.build();
return response;
}
#Override
public void enqueue(Callback responseCallback) {
}
#Override
public void cancel() {
}
#Override
public boolean isExecuted() {
return false;
}
#Override
public boolean isCanceled() {
return false;
}
public static class Factory implements Call.Factory {
#Override
public Call newCall(Request request) {
return new RetrofitCall(request);
}
}
}
You can use the following code snippet to run Retorifit2 with GAE limitations. It contains a lot of debugging stuffs free to remove in production and does not implement real async call.
okhttp3.Call.Factory gaeCallFactory = new okhttp3.Call.Factory() {
#Override
public okhttp3.Call newCall(final Request request) {
final URL url = request.url().url();
final String method = url.toString();
return new okhttp3.Call() {
#Override
public Request request() {
return request;
}
#Override
public Response execute() throws IOException {
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false);
if (request.body() != null) {
//TODO ajust for different needs
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
BufferedSink outbuf;
ByteArrayOutputStream out = new ByteArrayOutputStream();
outbuf = Okio.buffer(Okio.sink(out));
request.body().writeTo(outbuf);
outbuf.close();
logger.info("Calling " + method + "\n" + new String(out.toByteArray()));
outbuf = Okio.buffer(Okio.sink(connection.getOutputStream()));
request.body().writeTo(outbuf);
outbuf.close();
} else {
logger.info("Calling " + method);
}
final BufferedSource source = Okio.buffer(Okio.source(connection.getInputStream()));
if (connection.getResponseCode() != HttpServletResponse.SC_OK) {
throw new IOException("Fail to call " + method + " :: " + source.readUtf8());
}
Response response = new Response.Builder()
.code(connection.getResponseCode())
.message(connection.getResponseMessage())
.request(request)
.protocol(Protocol.HTTP_1_1)
.body(new ResponseBody() {
#Override
public MediaType contentType() {
return MediaType.parse(connection.getContentType());
}
#Override
public long contentLength() {
return connection.getContentLengthLong();
}
#Override
public BufferedSource source() {
return source;
}
})
.build();
logger.info("Call response code: " + response.code() + " message: " + response.message());
return response;
}
#Override
public void enqueue(Callback responseCallback) {
try {
responseCallback.onResponse(this, execute());
} catch (IOException e) {
responseCallback.onFailure(this, e);
}
}
#Override
public void cancel() {
}
#Override
public boolean isExecuted() {
return false;
}
#Override
public boolean isCanceled() {
return false;
}
};
}
};
Retrofit retrofit = new Retrofit.Builder()
.callFactory(gaeCallFactory)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(ENDPOINT_URI)
.build();
You need to use the Appengine URLFetchClient instead of the OkHttpClient. Like this:
import retrofit.appengine.UrlFetchClient;
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setConverter(new JacksonConverter())
.setEndpoint(ENDPOINT_PATH)
.setClient(new UrlFetchClient())
.build();
Please note this only works with Retrofit1, this will not work with Retrofit2 because it's coupled directly to OkHttp as explained by Jake Wharton here
iam using mediarecorder to record video in android application. I will start and stop recording video multiple times i will start recording on Action_down and stop on Action_up this is going on well and iam able to store and play video file in mobile .
my problem is that since i have to start and stop recording video multiple times i can't use single output file becuase everytime it will get over written so everytime iam passing new file name and iam appending that to one outputfile everytime.iam getting every individual file and final outputfile in mobile but final file is having only what i have recorded for the first time because from second tab if see the file.mp4.length()is zero why it is ? anyone please try to help me. my code is as follows
package com.example.longtouch;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.rtp.AudioGroup;
import android.net.rtp.AudioStream;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Handler.Callback;
import android.provider.MediaStore.Audio;
import android.provider.MediaStore.Files;
import android.provider.MediaStore.Video;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Toast;
import android.support.v4.app.NavUtils;
public class MainActivity extends Activity implements OnTouchListener{
int i=1;
File outputFile;
File f1;
File f2;
MediaRecorder mediaRecorder;
ThreadProgress mThreadProgress;
ThreadProgress2 mThreadProgress2;
public int eventAction;
Handler handler;
Handler mHandler;
Button myButton;
FrameLayout myCameraPreview;
Button submit;
Button submit1;
LinearLayout ll;
ProgressBar progressBar;
int progressStatus=0;
MyCameraSurfaceView myCameraSurfaceView;
Camera myCamera;
boolean recording;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recording=false;
myButton=(Button)findViewById(R.id.button_capture);
submit=(Button)findViewById(R.id.submit);
submit1=(Button)findViewById(R.id.submit1);
progressBar=(ProgressBar)findViewById(R.id.progress_bar);
progressBar.setMax(10000);
myCamera = getCameraInstance();
if(myCamera == null){
Toast.makeText(MainActivity.this,
"Fail to get Camera",
Toast.LENGTH_LONG).show();
}
// else
// myCamera.unlock();
myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
myCameraPreview=(FrameLayout)findViewById(R.id.camera_preview);
myCameraPreview.addView(myCameraSurfaceView);
ll=(LinearLayout)findViewById(R.id.ll);
myCameraPreview.setOnTouchListener(this);
outputFile=new File("/sdcard/myvideo.mp4");
if(outputFile.exists()){
outputFile.delete();
outputFile=new File("/sdcard/myvideo.mp4");
try {
outputFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
try {
outputFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
f1=new File("/sdcard/myvideo1.mp4");
if(f1.exists()){
f1.delete();
f1=new File("/sdcard/myvideo1.mp4");
try{
f1.createNewFile();
}
catch(Exception e){
e.printStackTrace();
}
}
else{
try{
f1.createNewFile();
}
catch(Exception e){
e.printStackTrace();
}
}
f2=new File("/sdcard/myvideo2.mp4");
if(f2.exists()){
f2.delete();
f2=new File("/sdcard/myvideo2.mp4");
try{
f2.createNewFile();
}
catch(Exception e){
e.printStackTrace();
}
}
else{
try{
f2.createNewFile();
}
catch(Exception e){
e.printStackTrace();
}
}
}
/* public int getFrontCameraId() {
CameraInfo ci = new CameraInfo();
for (int i = 0 ; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, ci);
if (ci.facing == CameraInfo.CAMERA_FACING_FRONT) return i;
}
return -1; // No front-facing camera found
}*/
private Camera getCameraInstance(){
// TODO Auto-generated method stub
Camera c = null;
try {
/* int index = getFrontCameraId();
if (index != -1)
c = Camera.open(index);*/
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
public void submit(View v){
// stop recording and release camera
// mediaRecorder.stop(); // stop the recording
// releaseMediaRecorder(); // release the MediaRecorder object
Log.d("outputFile",""+f1.length());
progressStatus=progressBar.getProgress();
//Exit after saved
// finish();
myButton.setText("capture");
recording=false;
submit.setVisibility(View.GONE);
}
public void submit1(View v){
// stop recording and release camera
// mediaRecorder.stop(); // stop the recording
// releaseMediaRecorder(); // release the MediaRecorder object
progressBar.setProgress(0);
progressStatus=0;
//Exit after saved
// finish();
myButton.setText("capture");
recording=false;
submit1.setVisibility(View.GONE);
}
public void display(View v){
Intent i=new Intent(this,VideoPlayer.class);
startActivity(i);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public boolean onTouch(View arg0, final MotionEvent event) {
// TODO Auto-generated method stub
eventAction=event.getAction();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
{
i=i+1;
Toast.makeText(getApplicationContext(),"action_down",Toast.LENGTH_SHORT).show();
//releaseCamera();
if(!prepareMediaRecorder()){
Toast.makeText(MainActivity.this,
"Fail in prepareMediaRecorder()!\n - Ended -",Toast.LENGTH_LONG).show();
finish();
}
progressBar.setProgress(progressStatus);
myButton.setText("STOP");
try{
mediaRecorder.start();
}
catch(Exception e){
e.printStackTrace();
Log.d("vd","exception at start method");
}
if(f1.exists()){
long l=f1.length();
Log.d("start","started"+l);
}
if(f2.exists()){
long m=f2.length();
Log.d("start","started"+m);
}
recording = true;
if(progressBar.getProgress()>=5000){
mThreadProgress2=new ThreadProgress2();
mThreadProgress2.start();
}
mHandler = new Handler(new Callback() {
public boolean handleMessage(final Message msg) {
runOnUiThread(new Runnable() {
public void run() {
if( event.getAction()!=MotionEvent.ACTION_UP){
progressBar.setProgress(msg.arg1);
}
if(progressBar.getProgress()==10000){
Log.d("unicorn","1000");
submit1.setVisibility(View.VISIBLE);
}
}
});
return false;
}
});
mThreadProgress=new ThreadProgress();
mThreadProgress.start();
handler = new Handler(new Callback() {
public boolean handleMessage(final Message msg) {
runOnUiThread(new Runnable() {
public void run() {
if( event.getAction()!=MotionEvent.ACTION_UP)
progressBar.setProgress(msg.arg1);
if(progressBar.getProgress()==5000){
submit.setVisibility(View.VISIBLE);
}
}
});
return false;
}
});
return true;
}
case MotionEvent.ACTION_UP:
{ // nothing to do
Toast.makeText(getApplicationContext(),"action_up",Toast.LENGTH_SHORT).show();
myButton.setText("capture");
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
try {
myCamera.reconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Exit after saved
// finish();
recording=false;
progressStatus=progressBar.getProgress();
if(i%2==0){
long len=f1.length();
Log.d("length",""+f1.getPath()+len);
Combine1 c1=new Combine1();
c1.start();
}
else{
long len=f2.length();
Log.d("length",""+f2.getPath()+len);
Combine2 c2=new Combine2();
c2.start();
}
break;
}
default:
return false;
}
return true;
}
private boolean prepareMediaRecorder(){
// myCamera = getCameraInstance();
mediaRecorder = new MediaRecorder();
myCamera.stopPreview();
myCamera.unlock();
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// mediaRecorder.setVideoSize(400,400);
if(i%2==0){
Log.d("outputfile",""+f1.getPath()+f1.length());
mediaRecorder.setOutputFile(f1.getPath());
Log.d("outputfile",""+f1.getPath()+f1.length());
}
else{
Log.d("outputfile",""+f2.getPath()+f2.length());
mediaRecorder.setOutputFile(f2.getPath());
Log.d("outputfile",""+f2.getPath()+f2.length());
}
mediaRecorder.setMaxDuration(10000); // Set max duration 10 sec.
mediaRecorder.setMaxFileSize(5000000); // Set max file size 5M
// mediaRecorder.setOnInfoListener(this);
mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d("prepare","illegalstateexception");
e.printStackTrace();
releaseMediaRecorder();
Toast.makeText(getApplicationContext(),"illegal state exception",Toast.LENGTH_SHORT).show();
return false;
} catch (IOException e) {
Log.d("prepare","ioexception");
e.printStackTrace();
releaseMediaRecorder();
Toast.makeText(getApplicationContext(),"IOexception",Toast.LENGTH_SHORT).show();
return false;
}
Log.d("after prepare","after prepare f1"+f1.length());
Log.d("after prepare","after prepare f2"+f2.length());
return true;
}
public void combine(String file){
Log.d("combine","combining"+file);
try{
File inputFile=new File(file);
FileInputStream fis=new FileInputStream(inputFile);
long inputlen=inputFile.length();
Log.d("combine","lengthbefore write"+inputlen);
File outputFile = new File("/sdcard/myvideo.mp4");
FileOutputStream fos = new FileOutputStream(outputFile,true);
byte fileContent[]= new byte[(int)inputFile.length()];
fis.read(fileContent);
long len=outputFile.length();
Log.d("combine","lenth"+len);
fos.write(fileContent);
fis.close();
fos.close();
inputlen=inputFile.length();
len=outputFile.length();
Log.d("combine","inputlength"+inputlen);
Log.d("combine","lenth"+len);
/* File f= new File(file);
boolean deleted = f.delete();
if(deleted){
Log.d("combine","deleted"+file);
} */
}
catch(Exception e){
e.printStackTrace();
}
}
#Override
protected void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
private void releaseMediaRecorder(){
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
// myCamera.lock(); // lock camera for later use
}
}
private void releaseCamera(){
if (myCamera != null){
myCamera.release(); // release the camera for other applications
myCamera = null;
}
}
public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
public MyCameraSurfaceView(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceChanged(SurfaceHolder holder, int format, int weight,
int height) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
}
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
public class ThreadProgress extends Thread implements Runnable {
int progressValue=progressStatus;
public void run() {
while( progressBar.getProgress()<5000 && eventAction!=MotionEvent.ACTION_UP ) {
Log.d("unicorn","in while loop"+progressValue);
progressValue++;
Message message = new Message();
message.arg1 = progressValue;
if(progressValue<=5000 && eventAction!=MotionEvent.ACTION_UP)
handler.sendMessage(message);
}
}
}
public class ThreadProgress2 extends Thread implements Runnable {
int progressValue=progressStatus;
#Override
public void run() {
while( progressBar.getProgress()<10000 && eventAction!=MotionEvent.ACTION_UP ) {
// try{
Log.d("unicorn2","in while loop"+progressValue);
progressValue++;
Message message = new Message();
message.arg1 = progressValue;
if(progressValue<=10000 && eventAction!=MotionEvent.ACTION_UP)
mHandler.sendMessage(message);
//Thread.sleep(1000);
//} catch (InterruptedException e){
// e.printStackTrace();
// break;
// }
}
}
}
public class Combine1 extends Thread implements Runnable{
public void run(){
try{
int c;
FileInputStream fin=new FileInputStream(f1);
FileOutputStream fout=new FileOutputStream(outputFile,true);
long len1=f1.length();
Log.d("length","myvideo1.mp4"+len1);
long len2=outputFile.length();
Log.d("length","myvideo.mp4"+len2);
while((c=fin.read())!=-1){
fout.write(c);
}
len2=outputFile.length();
Log.d("length","myvideo.mp4"+len2);
fin.close();
fout.flush();
fout.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}
public class Combine2 extends Thread implements Runnable{
public void run(){
try{
int j=0;
FileInputStream fin=new FileInputStream(f2);
FileOutputStream fout=new FileOutputStream(outputFile,true);
long len1=f2.length();
Log.d("length","myvideo2.mp4"+len1);
long len2=outputFile.length();
Log.d("length","myvideo.mp4"+len2);
while((j=fin.read())!=-1){
fout.write(j);
}
len2=outputFile.length();
Log.d("length","myvideo.mp4"+len2);
fin.close();
fout.flush();
fout.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
In order to combine multiple video files you should use mp4parser library : https://mp4parser.googlecode.com/svn/trunk/examples/src/main/java/com/googlecode/mp4parser/AppendExample.java