14b8d5eafa83c7ae75e18af877d2247b1da13242
[rtmpclient.git] / app / src / main / java / ai / suanzi / rtmpclient / MainActivity.java
1 package ai.suanzi.rtmpclient;
2
3 import android.app.Activity;
4 import android.app.PendingIntent;
5 import android.content.BroadcastReceiver;
6 import android.content.IntentFilter;
7 import android.graphics.ImageFormat;
8 import android.graphics.SurfaceTexture;
9 import android.hardware.usb.UsbDevice;
10 import android.hardware.usb.UsbManager;
11 import android.os.Environment;
12 import android.support.design.widget.TextInputEditText;
13 import android.support.v4.content.LocalBroadcastManager;
14 import android.support.v7.app.AppCompatActivity;
15 import android.os.Bundle;
16 import android.text.TextUtils;
17 import android.util.Log;
18 import android.view.SurfaceHolder;
19 import android.hardware.Camera;
20 import android.view.SurfaceView;
21 import android.view.View;
22 import android.widget.Button;
23 import android.widget.Toast;
24 import android.content.Context;
25 import android.content.pm.PackageManager;
26 import android.os.AsyncTask;
27
28 import java.io.File;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.io.IOException;
33 import java.util.concurrent.Executor;
34 import java.util.concurrent.ExecutorService;
35 import java.util.concurrent.Executors;
36 import android.content.Intent;
37 import java.io.OutputStream;
38 import android.hardware.usb.UsbManager;
39 import android.hardware.usb.UsbDeviceConnection;
40
41 import de.mindpipe.android.logging.log4j.LogConfigurator;
42 import org.apache.log4j.Level;
43 import org.apache.log4j.Logger;
44 import android.net.wifi.WifiManager;
45 import android.net.wifi.WifiInfo;
46 import android.content.ServiceConnection;
47 import android.content.ComponentName;
48
49 import ai.suanzi.rtmpclient.MyService.LocalBinder;
50 import android.os.IBinder;
51 import android.net.ConnectivityManager;
52
53 //"rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid";
54
55 public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback, MyService.MyServiceEventListener{
56
57     private static final String TAG = "MainActivity";
58     //private Ffmpeg ffmpeg;
59     //private Camera mCamera ;
60     //private StreamTask mStreamTask;
61     private SurfaceHolder mHolder;
62     private SurfaceView mSufaceView;
63     //private UVCCamera uvcCamera;
64     //ExecutorService mExecutor = Executors.newSingleThreadExecutor();
65     //Intent it = new Intent(getApplicationContext(), MyService.class);
66     //Intent intent = new Intent();
67
68     //private UsbManager usbManager;
69     //private UsbDevice usbCamera;
70
71     private Logger gLogger;
72
73     private Button mBtnStart;
74     private TextInputEditText mTextServer;
75     private TextInputEditText mTextUser;
76     private TextInputEditText mTextCamera;
77     private String mMacAddr = "";
78     //private CameraView mCameraView;
79     private String mRtmpUrl;
80     private NetworkMonitor networkMonitor;
81     private UsbMonitor mUsbMonitor;
82
83     boolean mBounded;
84     MyService mServer;
85     Intent mIntent;
86
87    // private ServiceReceiver mServiceReceiver;
88
89     private void configLog(){
90         try {
91             final LogConfigurator logConfigurator = new LogConfigurator();
92             String fname = getExternalFilesDir(null) + File.separator + "log.txt";
93             logConfigurator.setFileName(fname);
94             Log.e(TAG, "Log file is located at: " + fname);
95             logConfigurator.setRootLevel(Level.DEBUG);
96             logConfigurator.setLevel("org.apache", Level.ERROR);
97             logConfigurator.setMaxFileSize(1024 * 1024 * 10);
98             logConfigurator.configure();
99             gLogger = Logger.getLogger(getClass());
100         } catch (Exception e){
101             e.printStackTrace();
102         }
103     }
104
105     private void init(){
106         configLog();
107         gLogger.debug("#######################################");
108         // set config file
109         UserInfo.setConfigPath(getExternalFilesDir(null) + File.separator + "config");
110
111         this.mMacAddr = getMacAddr();
112         mBtnStart = findViewById(R.id.button);
113         mTextServer = findViewById(R.id.textServer);
114         mTextUser = findViewById(R.id.textUser);
115         mTextCamera = findViewById(R.id.textCamera);
116         mSufaceView = findViewById(R.id.surfaceView);
117         mHolder = mSufaceView.getHolder();
118         mHolder.addCallback(this);
119
120         mIntent = new Intent(this, MyService.class);
121         mUsbMonitor = new UsbMonitor(new UsbMonitor.UsbListener() {
122             @Override
123             public void onCameraConnected() {
124                 gLogger.error("onCameraConnected, current Usb Camera count: " + mUsbMonitor.getUsbCameraCount());
125                 doUnbindService();
126                 if(mUsbMonitor.hasUsbCamera()){
127                     doBindService();
128                 }
129             }
130
131             @Override
132             public void onCameraDisconnected() {
133                 gLogger.error("onCameraDisconnected, current camera count: " + mUsbMonitor.getUsbCameraCount());
134                 doUnbindService();
135                 if(mUsbMonitor.hasUsbCamera()){
136                     doBindService();
137                 }
138
139             }
140         }, this);
141
142         networkMonitor = new NetworkMonitor(new NetworkMonitor.NetworkListener() {
143             @Override
144             public void onWifiConnected() {
145                 gLogger.error("onWifiConnected");
146                 doBindService();
147             }
148
149             @Override
150             public void onWifiDisconnected() {
151                 gLogger.error("onWifiDisconnected");
152                 doUnbindService();
153             }
154
155             @Override
156             public void onWifiEnabled() {
157                 gLogger.error("onWifiEnabled");
158             }
159
160             @Override
161             public void onWifiDisabled() {
162                 gLogger.error("onWifiDisabled");
163             }
164         });
165         IntentFilter filter = new IntentFilter();
166         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
167         registerReceiver(networkMonitor, filter);
168     }
169
170
171     ServiceConnection mConnection = new ServiceConnection() {
172         @Override
173         public void onServiceDisconnected(ComponentName name) {
174             Toast.makeText(MainActivity.this, "Service is disconnected", 1000).show();
175             gLogger.error("onServiceDisconnected ---------->");
176             mBounded = false;
177             mServer = null;
178         }
179
180         @Override
181         public void onServiceConnected(ComponentName name, IBinder service) {
182             Toast.makeText(MainActivity.this, "Service is connected", 1000).show();
183             gLogger.error("onServiceConnected ---------->");
184             mBounded = true;
185             LocalBinder mLocalBinder = (LocalBinder)service;
186             mServer = mLocalBinder.getServiceInstance();
187             mServer.setServiceEventListener(MainActivity.this);
188             if(mServer.setRtmpUrl(UserInfo.getConfig().toUrl(mMacAddr))){
189                 mServer.startPreview(mHolder);
190             }
191         }
192     };
193
194     private void doBindService(){
195         if(!mBounded && canStartService()) {
196             gLogger.debug("doBindService");
197             bindService(mIntent, mConnection, BIND_AUTO_CREATE);
198         }
199     }
200
201     private void doUnbindService() {
202         if(mBounded){
203             gLogger.debug("doUnbindService");
204             unbindService(mConnection);
205             mBounded = false;
206         }
207     }
208
209     @Override
210     protected void onCreate(Bundle savedInstanceState) {
211         super.onCreate(savedInstanceState);
212         setContentView(R.layout.activity_main);
213
214         init();
215         loadConfig();
216
217         if(NetworkMonitor.isNetworkAvailable(this) && mUsbMonitor.hasUsbCamera()){
218             gLogger.error("Current network is available");
219             doBindService();
220         } else {
221             gLogger.error("Current network is NOT available");
222         }
223
224         mBtnStart.setText("start");
225         mBtnStart.setOnClickListener(new View.OnClickListener(){
226             @Override
227             public void onClick(View view){
228                 gLogger.error("----------> onClick");
229                 saveConfig();
230                 doUnbindService();
231             }
232         });
233     }
234
235     @Override
236     protected void onPause(){
237         super.onPause();
238         gLogger.error("OnPause --------->");
239     }
240
241     @Override
242     protected void onResume() {
243         super.onResume();
244         gLogger.error("OnResume ---------> ");
245     }
246
247     @Override
248     protected void onStop() {
249         super.onStop();
250         gLogger.debug("onStop --------->");
251     }
252
253     @Override
254     protected void onStart(){
255         super.onStart();
256         gLogger.debug("onStart --------->");
257     }
258
259     @Override
260     protected void onDestroy(){
261         super.onDestroy();
262         unregisterReceiver(networkMonitor);
263         gLogger.debug("onDestroy --------->");
264     }
265
266     @Override
267     protected void onRestart(){
268         super.onRestart();
269         gLogger.debug("onRestart ---------->");
270     }
271
272     // SurfaceHolder.Callback implementation
273     @Override
274     public void surfaceCreated(final SurfaceHolder holder){
275         gLogger.error("SurfacedCreated");
276     }
277
278     @Override
279     public void surfaceChanged(SurfaceHolder holder, int format, int widht, int height){
280         gLogger.error("surfaceChanged");
281         mHolder = holder;
282         if (mServer != null) {
283             mServer.startPreview(holder);
284         }
285     }
286
287     @Override
288     public void surfaceDestroyed(SurfaceHolder holder){ gLogger.debug("surfaceDestroyed");
289     }
290
291     @Override
292     public void  onPreviewFrame(final byte[] data, Camera camera){
293         gLogger.error("onPreviewFrame");
294
295     }
296
297
298     private String getMacAddr() {
299         WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
300         WifiInfo info = manager.getConnectionInfo();
301         return info.getMacAddress().replace(":", ""); //02:00:00:00:00:00 - 020000000000
302     }
303
304     private void loadConfig() {
305         UserInfo info = UserInfo.getConfig();
306         gLogger.error("server is:" + info.server);
307         mTextServer.setText(info.server.equals("") ? "rtmp://gpussh.suanzi.ai:1935/myapp" : info.server);
308         mTextUser.setText(info.user);
309         mTextCamera.setText(info.cameraId);
310         //mMacAddr = info.macAddr.equals("") ?  this.mMacAddr : info.macAddr;
311         gLogger.error("loadConfig - url is :" + info.toUrl(mMacAddr));
312     }
313
314     private void saveConfig() {
315         UserInfo info = UserInfo.getConfig();
316         info.update(mTextServer.getText().toString(), mTextUser.getText().toString(), mMacAddr, mTextCamera.getText().toString());
317         if(info.saveConfig()) {
318             Toast.makeText(getApplicationContext(), "Config saved", Toast.LENGTH_LONG).show();
319         } else {
320             Toast.makeText(getApplicationContext(), "Error: config saved", Toast.LENGTH_LONG).show();
321         }
322         gLogger.error("saveConfig - url: " + info.toUrl(mMacAddr));
323     }
324
325     private boolean canStartService(){
326         //gLogger.debug("canStartService - Camera: " + mUsbMonitor.hasUsbCamera() + ". Network: " + NetworkMonitor.isNetworkAvailable());
327         return mUsbMonitor.hasUsbCamera() && NetworkMonitor.isNetworkAvailable(this);
328     }
329
330     // MyServiceEventListener
331     @Override
332     public void onCameraError(String msg){
333         gLogger.error("onCameraEvent " + msg);
334     }
335
336     @Override
337     public void onEncoderError(String msg){
338         gLogger.error("onEncoderEvent: " + msg);
339     }
340
341     @Override
342     public void onIsPreviewing(String msg){
343         gLogger.error("onIsPreviewing: " + msg);
344     }
345
346
347 //    class ServiceReceiver extends BroadcastReceiver{
348 //        @Override
349 //        public void onReceive(Context context, Intent intent) {
350 //            String value = intent.getStringExtra("extra_data");
351 //            gLogger.error("ServiceReceiver onReceive - " + value);
352 //        }
353 //    }
354
355 //    private void changePermission(){
356 //        try {
357 //            Log.e(TAG, "change permission");
358 //            //Process sh = Runtime.getRuntime().exec(new String[]{"su", "-c", "chmod 666 /dev/video0"});
359 //
360 //            Process sh = Runtime.getRuntime().exec("/system/xbin/su", null,null);
361 //            //Process sh = Runtime.getRuntime().exec("su", null,null);
362 //
363 //            OutputStream  os = sh.getOutputStream();
364 //            os.write(("/system/bin/chmod 666 /dev/video0").getBytes("ASCII"));
365 //            //os.write(("/system/bin/echo 'wowo' >> /data/local/test").getBytes("ASCII"));
366 //            os.flush();
367 //            os.close();
368 //            sh.waitFor();
369 //
370 //
371 //        }catch (Exception e){
372 //            e.printStackTrace();
373 //        }
374 //    }
375 //
376 //    private boolean checkCameraHardware(Context context) {
377 //        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
378 //    }
379 //
380 //    private static Camera getCameraInstance(){
381 //        Camera c = null;
382 //        try {
383 //            Log.e(TAG, "Open Camera");
384 //            c = Camera.open(1);
385 //        } catch (Exception e){
386 //            e.printStackTrace();
387 //        }
388 //        return c;
389 //    }
390 //
391 //    private void configCamera(Camera camera){
392 //        Camera.Parameters paras = camera.getParameters();
393 //        gLogger.error("Supported Picture Sizes:");
394 //        for (Camera.Size cc : paras.getSupportedPictureSizes()){
395 //            gLogger.error(cc.width + "x" + cc.height);
396 //        }
397 //        gLogger.error("Supported Preview fps range:");
398 //        for(int[] i : paras.getSupportedPreviewFpsRange()){
399 //            gLogger.error("[" + i[0] + "," + i[1] + "]");
400 //        }
401 //        gLogger.error("Set parameters");
402 //        camera.setParameters(paras);
403 //        camera.setDisplayOrientation(0);
404 //        gLogger.error("Preview Format: " + paras.getPreviewFormat() + ". Size: " + paras.getPreviewSize().width + "x" + paras.getPreviewSize().height);
405 //        gLogger.error("Picture Format: " + paras.getPictureFormat() + ". Size: " + paras.getPictureSize().width + "x" + paras.getPictureSize().height);
406 //
407 //        try {
408 //            camera.setPreviewDisplay(mHolder);
409 //        } catch (IOException e){
410 //            e.printStackTrace();
411 //        }
412 //        //camera.setPreviewCallback(this);
413 //    }
414 //
415 //    private void switchToBackground(){
416 //        Intent i = new Intent();
417 //        i.setAction(Intent.ACTION_MAIN);
418 //        i.addCategory(Intent.CATEGORY_HOME);
419 //        this.startActivity(i);
420 //    }
421 }