fix some bug
[rtmpclient.git] / app / src / main / java / ai / suanzi / rtmpclient / MainActivity.java
1 package ai.suanzi.rtmpclient;
2
3 import android.content.IntentFilter;
4 import android.support.design.widget.TextInputEditText;
5 import android.support.v7.app.AppCompatActivity;
6 import android.os.Bundle;
7 import android.util.Log;
8 import android.view.SurfaceHolder;
9 import android.view.SurfaceView;
10 import android.view.View;
11 import android.widget.Button;
12 import android.widget.Toast;
13 import android.content.Context;
14
15 import java.io.File;
16 import android.content.Intent;
17 import de.mindpipe.android.logging.log4j.LogConfigurator;
18 import org.apache.log4j.Level;
19 import org.apache.log4j.Logger;
20 import android.net.wifi.WifiManager;
21 import android.net.wifi.WifiInfo;
22 import android.content.ServiceConnection;
23 import android.content.ComponentName;
24
25 import ai.suanzi.rtmpclient.MyService.LocalBinder;
26 import android.os.IBinder;
27 import android.net.ConnectivityManager;
28
29 //"rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90";
30
31 public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, MyService.MyServiceEventListener{
32
33     private static final String TAG = "MainActivity";
34     private Logger gLogger;
35
36     private SurfaceHolder mHolder;
37     private SurfaceView mSufaceView;
38     private Button mBtnStart;
39     private TextInputEditText mTextServer;
40     private TextInputEditText mTextUser;
41     private TextInputEditText mTextCamera;
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
47
48     boolean mBounded = false;
49     MyService mServer;
50     Intent mIntent;
51
52     private void configLog(){
53         try {
54             final LogConfigurator logConfigurator = new LogConfigurator();
55             String fname = getExternalFilesDir(null) + File.separator + "log.txt";
56             logConfigurator.setFileName(fname);
57             Log.e(TAG, "Log file is located at: " + fname);
58             logConfigurator.setRootLevel(Level.DEBUG);
59             logConfigurator.setLevel("org.apache", Level.ERROR);
60             logConfigurator.setMaxFileSize(1024 * 1024 * 10);
61             logConfigurator.configure();
62             gLogger = Logger.getLogger(getClass());
63         } catch (Exception e){
64             e.printStackTrace();
65         }
66     }
67
68     private void init(){
69         configLog();
70         gLogger.debug("#######################################");
71         // set config file
72         UserInfo.setConfigPath(getExternalFilesDir(null) + File.separator + "config");
73
74         this.mMacAddr = getMacAddr();
75         mBtnStart = findViewById(R.id.button);
76         mTextServer = findViewById(R.id.textServer);
77         mTextUser = findViewById(R.id.textUser);
78         mTextCamera = findViewById(R.id.textCamera);
79         mSufaceView = findViewById(R.id.surfaceView);
80         mHolder = mSufaceView.getHolder();
81         mHolder.addCallback(this);
82
83         mIntent = new Intent(this, MyService.class);
84         mUsbMonitor = new UsbMonitor(new UsbMonitor.UsbListener() {
85             @Override
86             public void onCameraConnected() {
87                 gLogger.error("onCameraConnected, current Usb Camera count: " + mUsbMonitor.getUsbCameraCount());
88                 doUnbindService();
89                 if(mUsbMonitor.hasUsbCamera()){
90                     doBindService();
91                 }
92             }
93
94             @Override
95             public void onCameraDisconnected() {
96                 gLogger.error("onCameraDisconnected, current camera count: " + mUsbMonitor.getUsbCameraCount());
97                 doUnbindService();
98                 if(mUsbMonitor.hasUsbCamera()){
99                     doBindService();
100                 }
101             }
102         }, this);
103
104         networkMonitor = new NetworkMonitor(new NetworkMonitor.NetworkListener() {
105             @Override
106             public void onWifiConnected() {
107                 gLogger.error("onWifiConnected");
108                 doBindService();
109             }
110
111             @Override
112             public void onWifiDisconnected() {
113                 gLogger.error("onWifiDisconnected");
114                 doUnbindService();
115             }
116
117             @Override
118             public void onWifiEnabled() {
119                 gLogger.error("onWifiEnabled");
120             }
121
122             @Override
123             public void onWifiDisabled() {
124                 gLogger.error("onWifiDisabled");
125             }
126         });
127         IntentFilter filter = new IntentFilter();
128         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
129         registerReceiver(networkMonitor, filter);
130
131         mServiceHealthMonitor = new ServiceHealthMonitor(new ServiceHealthMonitor.Callback() {
132             @Override
133             public void onNotHealthy() {
134                 gLogger.error("onNotHealthy, in " + INTERVAL + " seconds, the publishing may stopped or have error ");
135                 doUnbindService();
136                 doBindService();
137                 //restartApplication();
138             }
139         });
140         mServiceHealthMonitor.setInterval(INTERVAL); // 5 minutes
141     }
142
143
144     ServiceConnection mConnection = new ServiceConnection() {
145         @Override
146         public void onServiceDisconnected(ComponentName name) {
147             Toast.makeText(MainActivity.this, "Service is disconnected", 1000).show();
148             gLogger.error("onServiceDisconnected ---------->");
149             mBounded = false;
150             mServer = null;
151         }
152
153         @Override
154         public void onServiceConnected(ComponentName name, IBinder service) {
155             Toast.makeText(MainActivity.this, "Service is connected", 1000).show();
156             gLogger.error("onServiceConnected ---------->");
157             mBounded = true;
158             LocalBinder mLocalBinder = (LocalBinder)service;
159             mServer = mLocalBinder.getServiceInstance();
160             mServer.setServiceEventListener(MainActivity.this);
161             if(mServer.setRtmpUrl(UserInfo.getConfig().toUrl(mMacAddr))){
162                 mServer.startPreview(mHolder);
163             }
164
165
166         }
167     };
168
169     private void doBindService(){
170         gLogger.debug("doBindService");
171         if(!mBounded && canStartService()) {
172             gLogger.debug("Start service --------->");
173             bindService(mIntent, mConnection, BIND_AUTO_CREATE);
174         }
175     }
176
177     private void doUnbindService() {
178         gLogger.debug("doUnbindService");
179         if(mBounded){
180             gLogger.debug("Stop service <---------");
181             unbindService(mConnection);
182             mBounded = false;
183         }
184     }
185
186     @Override
187     protected void onCreate(Bundle savedInstanceState) {
188         super.onCreate(savedInstanceState);
189         setContentView(R.layout.activity_main);
190
191         init();
192         loadConfig();
193
194         if(NetworkMonitor.isNetworkAvailable(this) && mUsbMonitor.hasUsbCamera()){
195             gLogger.error("Current network is available");
196             doBindService();
197         } else {
198             gLogger.error("Current network NOT available or no USB Camera connected");
199         }
200
201         mBtnStart.setText("start");
202         mBtnStart.setOnClickListener(new View.OnClickListener(){
203             @Override
204             public void onClick(View view){
205                 gLogger.error("----------> onClick");
206                 saveConfig();
207                 doUnbindService();
208                 doBindService();
209             }
210         });
211
212         if(!mServiceHealthMonitor.isAlive()) {
213             gLogger.debug("mServiceHealthMonitor start, interval " + INTERVAL);
214             mServiceHealthMonitor.start();
215         }
216     }
217
218     @Override
219     protected void onPause(){
220         super.onPause();
221         gLogger.error("OnPause --------->");
222     }
223
224     @Override
225     protected void onResume() {
226         super.onResume();
227         gLogger.error("OnResume ---------> ");
228     }
229
230     @Override
231     protected void onStop() {
232         super.onStop();
233         gLogger.debug("onStop --------->");
234     }
235
236     @Override
237     protected void onStart(){
238         super.onStart();
239         gLogger.debug("onStart --------->");
240     }
241
242     @Override
243     protected void onDestroy(){
244         super.onDestroy();
245         mUsbMonitor.unregisterReceiver();
246         unregisterReceiver(networkMonitor);
247         unbindService(mConnection);
248         gLogger.debug("onDestroy --------->");
249     }
250
251     @Override
252     protected void onRestart(){
253         super.onRestart();
254         gLogger.debug("onRestart ---------->");
255     }
256
257     @Override
258     public void onBackPressed() {
259         gLogger.error("onBackPressed  --------->");
260         Intent intent = new Intent(Intent.ACTION_MAIN);
261         intent.addCategory(Intent.CATEGORY_HOME);
262         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
263         startActivity(intent);
264     }
265
266     // SurfaceHolder.Callback implementation
267     @Override
268     public void surfaceCreated(final SurfaceHolder holder){
269         gLogger.error("SurfacedCreated");
270     }
271
272     @Override
273     public void surfaceChanged(SurfaceHolder holder, int format, int widht, int height){
274         gLogger.error("surfaceChanged");
275         mHolder = holder;
276         if (mServer != null) {
277             mServer.startPreview(holder);
278         }
279     }
280
281     @Override
282     public void surfaceDestroyed(SurfaceHolder holder){ gLogger.debug("surfaceDestroyed");
283     }
284
285     private String getMacAddr() {
286         WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
287         WifiInfo info = manager.getConnectionInfo();
288         return info.getMacAddress().replace(":", ""); //02:00:00:00:00:00 - 020000000000
289     }
290
291     private void loadConfig() {
292         UserInfo info = UserInfo.getConfig();
293         gLogger.error("server is:" + info.server);
294         mTextServer.setText(info.server.equals("") ? "rtmp://gpussh.suanzi.ai:1935/myapp" : info.server);
295         mTextUser.setText(info.user);
296         mTextCamera.setText(info.cameraId);
297         //mMacAddr = info.macAddr.equals("") ?  this.mMacAddr : info.macAddr;
298         gLogger.error("loadConfig - url is :" + info.toUrl(mMacAddr));
299     }
300
301     private void saveConfig() {
302         UserInfo info = UserInfo.getConfig();
303         info.update(mTextServer.getText().toString(), mTextUser.getText().toString(), mMacAddr, mTextCamera.getText().toString());
304         if(info.saveConfig()) {
305             Toast.makeText(getApplicationContext(), "Config saved", Toast.LENGTH_LONG).show();
306         } else {
307             Toast.makeText(getApplicationContext(), "Error: config saved", Toast.LENGTH_LONG).show();
308         }
309         gLogger.error("saveConfig - url: " + info.toUrl(mMacAddr));
310     }
311
312     private boolean canStartService(){
313         return mUsbMonitor.hasUsbCamera() && NetworkMonitor.isNetworkAvailable(this);
314     }
315
316     // MyServiceEventListener
317     @Override
318     public void onCameraError(String msg){
319         gLogger.error("onCameraEvent " + msg);
320         if(mUsbMonitor.hasUsbCamera()){
321             //mServer.reopenCamera();
322         }
323     }
324
325     @Override
326     public void onEncoderError(String msg){
327         gLogger.error("onEncoderEvent: " + msg);
328     }
329
330     @Override
331     public void onPublishing(String msg){
332         gLogger.error("onPublishing: " + msg);
333         mServiceHealthMonitor.record();
334     }
335
336     private void restartApplication() {
337         final Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
338         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
339         startActivity(intent);
340     }
341 }