1 package ai.suanzi.rtmpclient;
3 import android.content.IntentFilter;
4 import android.hardware.Camera;
5 import android.support.design.widget.TextInputEditText;
6 import android.support.v7.app.ActionBar;
7 import android.support.v7.app.AppCompatActivity;
8 import android.os.Bundle;
9 import android.util.DisplayMetrics;
10 import android.util.Log;
11 import android.view.SurfaceHolder;
12 import android.view.SurfaceView;
13 import android.view.View;
14 import android.view.Window;
15 import android.view.WindowManager;
16 import android.widget.Button;
17 import android.widget.Toast;
18 import android.content.Context;
21 import android.content.Intent;
22 import de.mindpipe.android.logging.log4j.LogConfigurator;
23 import org.apache.log4j.Level;
24 import org.apache.log4j.Logger;
25 import android.net.wifi.WifiManager;
26 import android.net.wifi.WifiInfo;
27 import android.content.ServiceConnection;
28 import android.content.ComponentName;
30 import ai.suanzi.rtmpclient.MyService.LocalBinder;
31 import android.os.IBinder;
32 import android.net.ConnectivityManager;
33 import android.view.ViewGroup;
35 //"rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90";
37 public class MainActivity extends AppCompatActivity implements MyService.MyServiceEventListener, CameraView.Callback {
39 //private static final String TAG = "MainActivity";
40 private Logger gLogger;
42 private String mMacAddr = "";
43 private NetworkMonitor networkMonitor;
44 private UsbMonitor mUsbMonitor;
45 private ServiceHealthMonitor mServiceHealthMonitor;
46 private static final int INTERVAL = 3 * 60; // seconds
48 boolean mBounded = false;
52 private CameraView mCameraView;
54 private void configLog(){
56 final LogConfigurator logConfigurator = new LogConfigurator();
57 String fname = getExternalFilesDir(null) + File.separator + "log.txt";
58 logConfigurator.setFileName(fname);
59 logConfigurator.setRootLevel(Level.DEBUG);
60 logConfigurator.setLevel("org.apache", Level.ERROR);
61 logConfigurator.setMaxFileSize(1024 * 1024 * 10);
62 logConfigurator.configure();
63 gLogger = Logger.getLogger(getClass());
64 gLogger.error("#######################################");
65 gLogger.debug("Log file is located at: " + fname);
67 } catch (Exception e){
74 UserInfo.setConfigPath(getExternalFilesDir(null) + File.separator + "config");
76 this.mMacAddr = getMacAddr();
78 mIntent = new Intent(this, MyService.class);
79 mUsbMonitor = new UsbMonitor(new UsbMonitor.UsbListener() {
81 public void onCameraConnected() {
82 gLogger.error("onCameraConnected, current Usb Camera count: " + mUsbMonitor.getUsbCameraCount());
84 if(mUsbMonitor.hasUsbCamera()){
90 public void onCameraDisconnected() {
91 gLogger.error("onCameraDisconnected, current camera count: " + mUsbMonitor.getUsbCameraCount());
93 if(mUsbMonitor.hasUsbCamera()){
99 networkMonitor = new NetworkMonitor(new NetworkMonitor.NetworkListener() {
101 public void onWifiConnected() {
102 gLogger.error("onWifiConnected");
107 public void onWifiDisconnected() {
108 gLogger.error("onWifiDisconnected");
113 public void onWifiEnabled() {
114 gLogger.error("onWifiEnabled");
118 public void onWifiDisabled() {
119 gLogger.error("onWifiDisabled");
122 IntentFilter filter = new IntentFilter();
123 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
124 registerReceiver(networkMonitor, filter);
126 mServiceHealthMonitor = new ServiceHealthMonitor(new ServiceHealthMonitor.Callback() {
128 public void onNotHealthy() {
129 gLogger.error("onNotHealthy, in " + INTERVAL + " seconds, the publishing may stopped or have error ");
134 mServiceHealthMonitor.setInterval(INTERVAL); // 5 minutes
138 ServiceConnection mConnection = new ServiceConnection() {
140 public void onServiceDisconnected(ComponentName name) {
141 Toast.makeText(MainActivity.this, "Service is disconnected", 1000).show();
142 gLogger.error("onServiceDisconnected ---------->");
148 public void onServiceConnected(ComponentName name, IBinder service) {
149 Toast.makeText(MainActivity.this, "Service is connected", 1000).show();
150 gLogger.error("onServiceConnected ---------->");
152 LocalBinder mLocalBinder = (LocalBinder)service;
153 mServer = mLocalBinder.getServiceInstance();
154 mServer.setServiceEventListener(MainActivity.this);
155 if(mServer.setRtmpUrl(UserInfo.getConfig().toUrl(mMacAddr))){
156 //mServer.startPreview(mHolder);
157 mServer.startPreview(mCameraView.getHolder());
158 Camera.Size cs = mServer.getBestPictureSize();
159 mCameraView.setLayout(cs.width, cs.height);
166 private void doBindService(){
167 gLogger.debug("doBindService");
168 if(!mBounded && canStartService()) {
169 gLogger.debug("Start service --------->");
170 bindService(mIntent, mConnection, BIND_AUTO_CREATE);
174 private void doUnbindService() {
175 gLogger.debug("doUnbindService");
177 gLogger.debug("Stop service <---------");
178 unbindService(mConnection);
183 private void initCameraView (){
184 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
185 requestWindowFeature(Window.FEATURE_NO_TITLE);
186 getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
187 ///setContentView(R.layout.activity_main);
189 ActionBar actionBar = getSupportActionBar();
192 DisplayMetrics outMetrics = new DisplayMetrics();
193 this.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
195 CameraView.SCREEN_WIDTH = outMetrics.widthPixels;
196 CameraView.SCREEN_HEIGHT = outMetrics.heightPixels;
197 gLogger.debug("Screen size is w: " + CameraView.SCREEN_WIDTH + ", h: " + CameraView.SCREEN_HEIGHT);
201 mCameraView = new CameraView(getApplicationContext(), this);
202 setContentView(R.layout.activity_main);
204 ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(640, 480);
205 addContentView(mCameraView, lp);
206 //setContentView(mCameraView);
209 protected void onCreate(Bundle savedInstanceState) {
210 super.onCreate(savedInstanceState);
212 //gLogger.debug("#######################################");
218 if(NetworkMonitor.isNetworkAvailable(this) && mUsbMonitor.hasUsbCamera()){
219 gLogger.error("Current network is available");
222 gLogger.error("Current network NOT available or no USB Camera connected");
225 if(!mServiceHealthMonitor.isAlive()) {
226 gLogger.debug("mServiceHealthMonitor start, interval " + INTERVAL);
227 mServiceHealthMonitor.start();
232 protected void onPause(){
234 gLogger.error("OnPause --------->");
238 protected void onResume() {
240 gLogger.error("OnResume ---------> ");
244 protected void onStop() {
246 gLogger.debug("onStop --------->");
250 protected void onStart(){
252 gLogger.debug("onStart --------->");
256 protected void onDestroy(){
258 mUsbMonitor.unregisterReceiver();
259 unregisterReceiver(networkMonitor);
260 unbindService(mConnection);
261 gLogger.debug("onDestroy --------->");
265 protected void onRestart(){
267 gLogger.debug("onRestart ---------->");
271 public void onBackPressed() {
272 gLogger.error("onBackPressed --------->");
273 Intent intent = new Intent(Intent.ACTION_MAIN);
274 intent.addCategory(Intent.CATEGORY_HOME);
275 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
276 startActivity(intent);
279 private String getMacAddr() {
280 WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
281 WifiInfo info = manager.getConnectionInfo();
282 return info.getMacAddress().replace(":", ""); //02:00:00:00:00:00 - 020000000000
285 private void loadConfig() {
286 // UserInfo info = UserInfo.getConfig();
287 // gLogger.error("server is:" + info.server);
288 // mTextServer.setText(info.server.equals("") ? "rtmp://gpussh.suanzi.ai:1935/myapp" : info.server);
289 // mTextUser.setText(info.user);
290 // //mMacAddr = info.macAddr.equals("") ? this.mMacAddr : info.macAddr;
291 // gLogger.error("loadConfig - url is :" + info.toUrl(mMacAddr));
294 private void saveConfig() {
295 UserInfo info = UserInfo.getConfig();
296 //info.update(mTextServer.getText().toString(), mTextUser.getText().toString(), mMacAddr, mTextCamera.getText().toString());
297 if(info.saveConfig()) {
298 Toast.makeText(getApplicationContext(), "Config saved", Toast.LENGTH_LONG).show();
300 Toast.makeText(getApplicationContext(), "Error: config saved", Toast.LENGTH_LONG).show();
302 gLogger.error("saveConfig - url: " + info.toUrl(mMacAddr));
305 private boolean canStartService(){
306 return mUsbMonitor.hasUsbCamera() && NetworkMonitor.isNetworkAvailable(this);
309 // MyServiceEventListener
311 public void onCameraError(String msg){
312 gLogger.error("onCameraEvent " + msg);
313 //if(mUsbMonitor.hasUsbCamera()){
314 //mServer.reopenCamera();
319 public void onEncoderError(String msg){
320 gLogger.error("onEncoderError: " + msg);
326 public void onPublishing(String msg){
327 mServiceHealthMonitor.record();
331 public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height){
333 mServer.startPreview(holder);
337 private void restartApplication() {
338 final Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
339 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
340 startActivity(intent);