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