X-Git-Url: http://47.100.26.94:8080/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fai%2Fsuanzi%2Frtmpclient%2FMainActivity.java;h=5779298d26f34fcbe9edc831d3b193b7efe5c5c8;hb=d1a43ff97228c10a4eaef604bd40eb8be3fcf8f6;hp=708ed3c8923156923bcabde439a14939e0488333;hpb=8af8da070650175d3a35a840fbd339ee572d144f;p=rtmpclient.git diff --git a/app/src/main/java/ai/suanzi/rtmpclient/MainActivity.java b/app/src/main/java/ai/suanzi/rtmpclient/MainActivity.java index 708ed3c..5779298 100644 --- a/app/src/main/java/ai/suanzi/rtmpclient/MainActivity.java +++ b/app/src/main/java/ai/suanzi/rtmpclient/MainActivity.java @@ -1,42 +1,25 @@ package ai.suanzi.rtmpclient; -import android.app.Activity; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; import android.content.IntentFilter; -import android.graphics.ImageFormat; -import android.graphics.SurfaceTexture; -import android.hardware.usb.UsbDevice; -import android.hardware.usb.UsbManager; -import android.os.Environment; +import android.hardware.Camera; +import android.net.Uri; import android.support.design.widget.TextInputEditText; +import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; -import android.text.TextUtils; +import android.util.DisplayMetrics; import android.util.Log; import android.view.SurfaceHolder; -import android.hardware.Camera; import android.view.SurfaceView; import android.view.View; +import android.view.Window; +import android.view.WindowManager; import android.widget.Button; import android.widget.Toast; import android.content.Context; -import android.content.pm.PackageManager; -import android.os.AsyncTask; import java.io.File; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.io.IOException; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import android.content.Intent; -import java.io.OutputStream; -import android.hardware.usb.UsbManager; -import android.hardware.usb.UsbDeviceConnection; - import de.mindpipe.android.logging.log4j.LogConfigurator; import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -47,73 +30,98 @@ import android.content.ComponentName; import ai.suanzi.rtmpclient.MyService.LocalBinder; import android.os.IBinder; +import android.net.ConnectivityManager; +import android.view.ViewGroup; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.client.methods.CloseableHttpResponse; + +//import org.apache.http.client.methods; +import android.view.MotionEvent; +import android.graphics.Color; +import android.os.Build; +import android.content.pm.ActivityInfo; +import android.view.Display; +import android.graphics.Point; +import android.view.ViewConfiguration; +import java.lang.reflect.Field; +import android.view.Menu; +import android.view.MenuItem; + +public class MainActivity extends AppCompatActivity implements MyService.MyServiceEventListener, CameraView.Callback { -//"rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid"; + private Logger gLogger; + private NetworkMonitor networkMonitor; + private UsbMonitor mUsbMonitor; + private ServiceHealthMonitor mServiceHealthMonitor; + private static final int INTERVAL = 3 * 60; // seconds -public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback{ + boolean mBounded = false; + MyService mServer; + Intent mIntent; + private boolean isFullScreen = false; - private static final String TAG = "PENG"; - //private Ffmpeg ffmpeg; - //private Camera mCamera ; - //private StreamTask mStreamTask; - private SurfaceHolder mHolder; - private SurfaceView mSufaceView; - //private UVCCamera uvcCamera; - //ExecutorService mExecutor = Executors.newSingleThreadExecutor(); - //Intent it = new Intent(getApplicationContext(), MyService.class); - Intent intent = new Intent(); + private CameraView mCameraView; - //private UsbManager usbManager; - //private UsbDevice usbCamera; + private void init(){ - private Logger gLogger; + mIntent = new Intent(this, MyService.class); + mUsbMonitor = new UsbMonitor(new UsbMonitor.UsbListener() { + @Override + public void onCameraConnected() { + gLogger.error("onCameraConnected, current Usb Camera count: " + mUsbMonitor.getUsbCameraCount()); + doUnbindService(); + if(mUsbMonitor.hasUsbCamera()){ + doBindService(); + } + } - private Button mBtnStart; - private TextInputEditText mTextServer; - private TextInputEditText mTextUser; - private TextInputEditText mTextCamera; - private String mMacAddr = ""; - //private CameraView mCameraView; - private String mRtmpUrl; + @Override + public void onCameraDisconnected() { + gLogger.error("onCameraDisconnected, current camera count: " + mUsbMonitor.getUsbCameraCount()); + doUnbindService(); + if(mUsbMonitor.hasUsbCamera()){ + doBindService(); + } + } + }, this); - boolean mBounded; - MyService mServer; - Intent mIntent; + networkMonitor = new NetworkMonitor(new NetworkMonitor.NetworkListener() { + @Override + public void onWifiConnected() { + gLogger.error("onWifiConnected"); + doBindService(); + } - private void configLog(){ - try { - final LogConfigurator logConfigurator = new LogConfigurator(); - String fname = getExternalFilesDir(null) + File.separator + "log.txt"; - logConfigurator.setFileName(fname); - Log.e(TAG, "Log file is located at: " + fname); - logConfigurator.setRootLevel(Level.DEBUG); - logConfigurator.setLevel("org.apache", Level.ERROR); - logConfigurator.setMaxFileSize(1024 * 1024 * 10); - logConfigurator.configure(); - gLogger = Logger.getLogger(getClass()); - } catch (Exception e){ - e.printStackTrace(); - } - } + @Override + public void onWifiDisconnected() { + gLogger.error("onWifiDisconnected"); + doUnbindService(); + } - private void init(){ - configLog(); - gLogger.debug("#######################################"); - // set config file - UserInfo.setConfigPath(getExternalFilesDir(null) + File.separator + "config"); - - this.mMacAddr = getMacAddr(); - mBtnStart = findViewById(R.id.button); - mTextServer = findViewById(R.id.textServer); - mTextUser = findViewById(R.id.textUser); - mTextCamera = findViewById(R.id.textCamera); - mSufaceView = findViewById(R.id.surfaceView); - mHolder = mSufaceView.getHolder(); - mHolder.addCallback(this); - - - //intent.setPackage(this.getPackageName()); // init service - //intent.setAction("ai.suanzi.rtmpclient.service"); + @Override + public void onWifiEnabled() { + gLogger.error("onWifiEnabled"); + } + + @Override + public void onWifiDisabled() { + gLogger.error("onWifiDisabled"); + } + }); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + registerReceiver(networkMonitor, filter); + + mServiceHealthMonitor = new ServiceHealthMonitor(new ServiceHealthMonitor.Callback() { + @Override + public void onNotHealthy() { + gLogger.error("onNotHealthy, in " + INTERVAL + " seconds, the publishing may stopped or have error "); + doUnbindService(); + doBindService(); + } + }); + mServiceHealthMonitor.setInterval(INTERVAL); } @@ -133,48 +141,107 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal mBounded = true; LocalBinder mLocalBinder = (LocalBinder)service; mServer = mLocalBinder.getServiceInstance(); - if(mServer.setRtmpUrl(UserInfo.getConfig().toUrl())){ - mServer.startPreview(mHolder); + mServer.setServiceEventListener(MainActivity.this); + if(mServer.setRtmpUrl(UserInfo.toUrl())){ + mServer.startPreview(mCameraView.getHolder()); + Camera.Size cs = mServer.getBestPictureSize(); + mCameraView.setLayout(cs.width, cs.height); + } else { + gLogger.error("onServiceConnected - setRtmpUrl failed"); } - } }; + private void doBindService(){ + gLogger.debug("doBindService"); + if(!mBounded && canStartService()) { + gLogger.debug("Start service --------->"); + bindService(mIntent, mConnection, BIND_AUTO_CREATE); + } + } + + private void doUnbindService() { + gLogger.debug("doUnbindService"); + if(mBounded){ + gLogger.debug("Stop service <---------"); + unbindService(mConnection); + mBounded = false; + } + } + + private class ScreenSize { + public ScreenSize(){ } + public int width = 0; + public int height = 0; + } + + private ScreenSize getScreenSize(){ + ScreenSize size = new ScreenSize(); + WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); + final Display display = windowManager.getDefaultDisplay(); + Point outPoint = new Point(); + if(Build.VERSION.SDK_INT >= 19) { + display.getRealSize(outPoint); // include navigation bar + } else { + display.getSize(outPoint); // exclude navigation bar + } + size.width = outPoint.x; + size.height = outPoint.y; + + return size; + } + + private void initCameraView (){ + + ScreenSize size = getScreenSize(); + CameraView.SCREEN_WIDTH = size.width; + CameraView.SCREEN_HEIGHT = size.height; + gLogger.debug("Screen size is w: " + CameraView.SCREEN_WIDTH + ", h: " + CameraView.SCREEN_HEIGHT); + + mCameraView = new CameraView(getApplicationContext(), this); + setContentView(R.layout.activity_main); + + ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(640, 480); + addContentView(mCameraView, lp); + //setContentView(mCameraView); + } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - + LogUtil.config(this); + gLogger = Logger.getLogger(getClass()); + gLogger.error("onCreate ---------> "); + UserInfo.readConfig(getExternalFilesDir(null) + File.separator + "config", getMacAddr()); + initCameraView(); init(); - loadConfig(); - - //startService(intent); - mIntent = new Intent(this, MyService.class); - bindService(mIntent, mConnection, BIND_AUTO_CREATE); + if(canStartService()){ + gLogger.error("Current network is available"); + doBindService(); + } else { + gLogger.error("Current network NOT available or no USB Camera connected"); + } - mBtnStart.setText("start"); - mBtnStart.setOnClickListener(new View.OnClickListener(){ - @Override - public void onClick(View view){ - gLogger.error("----------> onClick"); - saveConfig(); - unbindService(mConnection); - bindService(mIntent, mConnection, BIND_AUTO_CREATE); - } - }); + if(!mServiceHealthMonitor.isAlive()) { + gLogger.debug("mServiceHealthMonitor start, interval " + INTERVAL); + mServiceHealthMonitor.start(); + } + ////////// LogUtil.sendLogs(); /// Log test + //LogUtil.sendLogs(); + // test + //new CheckVersionInfoTask(MainActivity.this).execute(); } @Override protected void onPause(){ super.onPause(); - gLogger.error("OnPause --------->"); + gLogger.debug("OnPause --------->"); } @Override protected void onResume() { super.onResume(); - gLogger.error("OnResume ---------> "); + gLogger.debug("OnResume ---------> "); } @Override @@ -192,6 +259,9 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal @Override protected void onDestroy(){ super.onDestroy(); + mUsbMonitor.unregisterReceiver(); + unregisterReceiver(networkMonitor); + unbindService(mConnection); gLogger.debug("onDestroy --------->"); } @@ -201,176 +271,132 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal gLogger.debug("onRestart ---------->"); } - - - - // SurfaceHolder.Callback implementation @Override - public void surfaceCreated(final SurfaceHolder holder){ - gLogger.error("SurfacedCreated"); + public void onBackPressed() { + gLogger.debug("onBackPressed --------->"); + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_HOME); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); } @Override - public void surfaceChanged(SurfaceHolder holder, int format, int widht, int height){ - gLogger.error("surfaceChanged"); - mHolder = holder; - if (mServer != null) { - mServer.startPreview(holder); + public boolean onTouchEvent(MotionEvent event) { + if(event.getAction() == MotionEvent.ACTION_UP) { + toggleFullScreen(); } + return super.onTouchEvent(event); } @Override - public void surfaceDestroyed(SurfaceHolder holder){ gLogger.debug("surfaceDestroyed"); + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if (hasFocus && Build.VERSION.SDK_INT >= 19) { + toggleFullScreen(); + } } @Override - public void onPreviewFrame(final byte[] data, Camera camera){ - gLogger.error("onPreviewFrame"); - + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return true; } - private String getMacAddr() { WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); WifiInfo info = manager.getConnectionInfo(); + gLogger.debug("Mac Address is " + info.getMacAddress()); return info.getMacAddress().replace(":", ""); //02:00:00:00:00:00 - 020000000000 } - private void loadConfig() { - UserInfo info = UserInfo.getConfig(); - mTextServer.setText(info.server); - mTextUser.setText(info.user); - mTextCamera.setText(info.cameraId); - //mMacAddr = info.macAddr.equals("") ? this.mMacAddr : info.macAddr; - gLogger.error("loadConfig - url is :" + info.toUrl()); - } - - private void saveConfig() { - UserInfo info = UserInfo.getConfig(); - info.update(mTextServer.getText().toString(), mTextUser.getText().toString(), mMacAddr, mTextCamera.getText().toString()); - if(info.saveConfig()) { - Toast.makeText(getApplicationContext(), "Config saved", Toast.LENGTH_LONG).show(); - } else { - Toast.makeText(getApplicationContext(), "Error: config saved", Toast.LENGTH_LONG).show(); + private boolean canStartService(){ + if(System.getProperty("os.arch").equals("i686")){ + return true; } - gLogger.error("saveConfig - url: " + info.toUrl()); + return mUsbMonitor.hasUsbCamera() && NetworkMonitor.isNetworkAvailable(this); } - private void changePermission(){ - try { - Log.e(TAG, "change permission"); - //Process sh = Runtime.getRuntime().exec(new String[]{"su", "-c", "chmod 666 /dev/video0"}); + // MyServiceEventListener + @Override + public void onCameraError(String msg){ + gLogger.error("onCameraEvent " + msg); + //if(mUsbMonitor.hasUsbCamera()){ + //mServer.reopenCamera(); + //} + } - Process sh = Runtime.getRuntime().exec("/system/xbin/su", null,null); - //Process sh = Runtime.getRuntime().exec("su", null,null); + @Override + public void onEncoderError(String msg){ + gLogger.error("onEncoderError: " + msg); + doUnbindService(); + doBindService(); + } - OutputStream os = sh.getOutputStream(); - os.write(("/system/bin/chmod 666 /dev/video0").getBytes("ASCII")); - //os.write(("/system/bin/echo 'wowo' >> /data/local/test").getBytes("ASCII")); - os.flush(); - os.close(); - sh.waitFor(); + @Override + public void onPublishing(String msg){ + mServiceHealthMonitor.record(); + } + @Override + public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height){ + if(mServer != null){ + mServer.startPreview(holder); + } + } - }catch (Exception e){ - e.printStackTrace(); + @Override + public boolean onOptionsItemSelected(MenuItem item) + { + switch (item.getItemId()) { + case R.id.action_settings: + Toast.makeText(MainActivity.this, "setting", Toast.LENGTH_SHORT).show(); + break; + case R.id.action_mail: + gLogger.debug("onOptionsItemSelected - send mail button clicked"); + LogUtil.sendLogs(); + break; + case R.id.action_about: + break; + case R.id.action_update: + gLogger.debug("onOptionsItemSelected - check update"); + new CheckVersionInfoTask(this).execute(); } + return super.onOptionsItemSelected(item); } - private boolean checkCameraHardware(Context context) { - return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA); + private void restartApplication() { + final Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); } - private static Camera getCameraInstance(){ - Camera c = null; - try { - Log.e(TAG, "Open Camera"); - c = Camera.open(1); - } catch (Exception e){ - e.printStackTrace(); + private void toggleFullScreen (){ + View decorView = getWindow().getDecorView(); + if(!isFullScreen) { + decorView.setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + } else { + decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_VISIBLE); } - return c; + isFullScreen = !isFullScreen; } - private void configCamera(Camera camera){ - Camera.Parameters paras = camera.getParameters(); - gLogger.error("Supported Picture Sizes:"); - for (Camera.Size cc : paras.getSupportedPictureSizes()){ - gLogger.error(cc.width + "x" + cc.height); - } - gLogger.error("Supported Preview fps range:"); - for(int[] i : paras.getSupportedPreviewFpsRange()){ - gLogger.error("[" + i[0] + "," + i[1] + "]"); - } - gLogger.error("Set parameters"); - camera.setParameters(paras); - camera.setDisplayOrientation(0); - gLogger.error("Preview Format: " + paras.getPreviewFormat() + ". Size: " + paras.getPreviewSize().width + "x" + paras.getPreviewSize().height); - gLogger.error("Picture Format: " + paras.getPictureFormat() + ". Size: " + paras.getPictureSize().width + "x" + paras.getPictureSize().height); + private void getOverflowMenu() { try { - camera.setPreviewDisplay(mHolder); - } catch (IOException e){ + ViewConfiguration config = ViewConfiguration.get(this); + Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); + if(menuKeyField != null) { + menuKeyField.setAccessible(true); + menuKeyField.setBoolean(config, false); + } + } catch (Exception e) { e.printStackTrace(); } - //camera.setPreviewCallback(this); } - - private void switchToBackground(){ - Intent i = new Intent(); - i.setAction(Intent.ACTION_MAIN); - i.addCategory(Intent.CATEGORY_HOME); - this.startActivity(i); - } - -// -// // class StreamTask AsyncTask -// private class StreamTask extends AsyncTask{ -// private byte[] data; -// -// StreamTask(byte[] data){ -// this.data = data; -// } -// -// @Override -// protected Void doInBackground(Void... params) { -// -// if (this.data != null){ -// Log.e(TAG, "fps: " + mCamera.getParameters().getPreviewFrameRate()); -// ffmpeg.process(this.data); -// } -// return null; -// } -// } - - /*if (null != mStreamTask){ - switch (mStreamTask.getStatus()){ - case RUNNING: - Log.e(TAG, "onPreviewFrame Running"); - return; - case PENDING: - Log.e(TAG,"OnPreviewFrame Pending"); - mStreamTask.cancel(false); - break; - } - } - mStreamTask = new StreamTask(data); - mStreamTask.execute((Void)null); -*/ - -// ong endTime = System.currentTimeMillis(); -// mExecutor.execute(new Runnable() { -// @Override -// public void run() { -// //long encodeTime = System.currentTimeMillis(); -// ffmpeg.process(data); - //Log.e(TAG, "编码第:" + (encodeCount++) + "帧,耗时:" + (System.currentTimeMillis() - encodeTime)); -// } -// }); - //Log.e(TAG, "采集第:" + (++count) + "帧,距上一帧间隔时间:" -// + (endTime - previewTime) + " " + Thread.currentThread().getName()); -// previewTime = endTime;*/ - - - }