找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888
查看: 7307|回复: 4

折腾OSCAM之三---(转帖)Oscam for Android

[复制链接]
本帖最后由 兔巴哥 于 2019-11-7 18:18 编辑

之一之二后,一直折腾怎么样将oscam打包成安卓的app,无奈功力不够,只能进行到编译出主程序一步,遂放弃.....近日发现了很有意义的博文,于是分享给大家。(内容有删减)


一、Compiling Oscam for Android
1、首先配置Linux系统
2、下载最新的Linux 64位(x86)Android NDK,可以在这里下载https://developer.android.com/ndk/downloads/index.html,在写这篇文章的时候,最新的稳定版本是r13b。
将NDK文件解压到Home,然后cd到build / tools文件夹中,以便于构建用于交叉编译的工具链。
  1. cd ~/android-ndk-r13b/build/tools
  2. export TOOLCHAIN=~/android-toolchain
  3. ./make_standalone_toolchain.py --arch arm --api 24 --install-dir $TOOLCHAIN
复制代码
这个命令在你的Home上创建一个android工具链。
3、在使用这个工具链交叉编译OScam之前,我们还需要编译OpenSSL,否则在使用cccam协议时会出现无法连接的情况。
下载,解压缩和构建OpenSSL:
  1. cd ~
  2. wget http://www.openssl.org/source/openssl-1.0.1g.tar.gz
  3. tar -xf openssl-1.0.1g.tar.gz
  4. cd openssl-1.0.1g
  5. export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
  6. export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
  7. ./Configure --prefix=$TOOLCHAIN/sysroot/usr android
  8. make
  9. make install_sw
复制代码
检查Oscam svn并编译添加openssl。
  1. cd ~
  2. svn checkout http://www.streamboard.tv/svn/oscam/trunk oscam-svn
  3. cd oscam-svn
  4. ./config.sh --enable WEBIF WITH_SSL
复制代码
4、交叉编译Android上运行的Oscam。
  1. make static EXTRA_FLAGS="-pie" LIB_RT= LIB_PTHREAD= CROSS=$TOOLCHAIN/bin/arm-linux-androideabi-
复制代码
如果一切正常,应该在oscam-svn的Distribution文件夹中生成一个在Android环境中运行的程序文件,比如oscam-1.20-unstable_svn11347-arm-linux-androideabi-ssl
当然,这不是一个APK,刚刚做的只是编译出来了本机C代码。这个在安卓设备运行比较麻烦,而且也不容易实现。
APK是一个包含字节码(编译的java代码)和资源的包,它将在android java虚拟机(可以是Dalvik或ART,取决于您的Android版本)内运行。
那么如何在安卓设备上安装并运行该程序呢?
我们基本上需要构建一个包含我们的本地二进制文件作为资源的Android应用程序(APK),将其提取到可执行的位置(不在SDCard上运行),使其可执行并运行。


二、Building an Oscam APK for Android在上一节中如果已经编译出Oscam二进制文件,那么这一步生成APK的过程无论是Linux系统还是Windows系统都是可以完成的。
1、使用Android Studio创建一个新的项目。

2、在“res”文件夹下创建一个“raw”文件夹。

3、把oscam二进制文件改名为“oscam”并放在raw文件夹下。

4、添加一些小部件到用户界面,并做一些代码。

5、布局的XML代码应该是这样的:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:tools="http://schemas.android.com/tools"
  4.     android:id="@+id/activity_main"
  5.     android:layout_width="match_parent"
  6.     android:layout_height="match_parent"
  7.     android:paddingBottom="@dimen/activity_vertical_margin"
  8.     android:paddingLeft="@dimen/activity_horizontal_margin"
  9.     android:paddingRight="@dimen/activity_horizontal_margin"
  10.     android:paddingTop="@dimen/activity_vertical_margin"
  11.     tools:context="com.tekreaders.myoscamapk.MainActivity">

  12.     <Button
  13.         android:id="@+id/startButton"
  14.         android:layout_alignParentTop="true"
  15.         android:layout_width="wrap_content"
  16.         android:layout_height="wrap_content"
  17.         android:text="Start Oscam"
  18.         android:onClick="startOscam"
  19.         />
  20.     <Button
  21.         android:id="@+id/stopButton"
  22.         android:layout_toRightOf="@+id/startButton"
  23.         android:layout_alignParentTop="true"
  24.         android:layout_width="wrap_content"
  25.         android:layout_height="wrap_content"
  26.         android:text="Stop Oscam"
  27.         android:onClick="stopOscam"
  28.         />

  29.     <TextView
  30.         android:id="@+id/outputView"
  31.         android:layout_alignParentBottom="true"
  32.         android:layout_alignParentRight="true"
  33.         android:layout_alignParentLeft="true"
  34.         android:layout_below="@+id/startButton"
  35.         android:layout_width="match_parent"
  36.         android:layout_height="match_parent"
  37.         android:maxLines="200"
  38.         android:scrollbars="vertical"
  39.         android:text="Oscam log will be displayed here..."
  40.          />
  41. </RelativeLayout>
复制代码
6、整个MainActivity的代码:
  1. public class MainActivity extends AppCompatActivity {
  2.     TextView outputView;
  3.     Button startButton;
  4.     Button stopButton;

  5.     private String confDir = Environment.getExternalStorageDirectory().getPath() + "/oscam";
  6.     private String tmpDir = Environment.getExternalStorageDirectory().getPath() + "/oscam/tmp";
  7.     private String oscamFilename = "";
  8.     private Process oscamProcess;

  9.     @Override
  10.     protected void onCreate(Bundle savedInstanceState) {
  11.         super.onCreate(savedInstanceState);
  12.         setContentView(R.layout.activity_main);
  13.         outputView = (TextView)findViewById(R.id.outputView);
  14.         startButton = (Button)findViewById(R.id.startButton);
  15.         stopButton = (Button)findViewById(R.id.stopButton);
  16.         outputView.setMovementMethod(new ScrollingMovementMethod());
  17.         requestPermissions();
  18.     }

  19.     //request the runtime permissions, this required since Marshmallow
  20.     public void requestPermissions() {
  21.         if (Build.VERSION.SDK_INT >= 23) {
  22.             ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
  23.         }
  24.     }

  25.     //output logs and enable/disable buttons according to the running state
  26.     public void setStatus(final boolean running, final String message){
  27.         runOnUiThread(new Runnable() {
  28.             @Override
  29.             public void run() {
  30.                 if (message!=null) {
  31.                     outputView.setText(outputView.getText()+"\n"+message);
  32.                     if (outputView.getVisibility() == View.VISIBLE) {
  33.                         final int scrollAmount = outputView.getLayout().getLineTop(outputView.getLineCount()) - outputView.getHeight();
  34.                         if (scrollAmount > 0)
  35.                             outputView.scrollTo(0, scrollAmount);
  36.                         else
  37.                             outputView.scrollTo(0, 0);
  38.                     }
  39.                 }
  40.                 startButton.setEnabled(!running);
  41.                 stopButton.setEnabled(running);
  42.             }
  43.         });
  44.     }

  45.     public void startOscam(View view){
  46.         if (oscamProcess == null) {
  47.             //run this process on a new thread to avoid UI blocking
  48.             new Thread(new Runnable() {
  49.                 @Override
  50.                 public void run() {
  51.                     try {
  52.                         setStatus(true, "Initializing...");
  53.                         //check the config and tmp folders
  54.                         File cdir = new File(confDir);
  55.                         File tdir = new File(tmpDir);
  56.                         boolean confDirExists = cdir.exists();
  57.                         boolean tmpDirExists = tdir.exists();
  58.                         if (!confDirExists)
  59.                             confDirExists = cdir.mkdir();
  60.                         if (!tmpDirExists)
  61.                             tmpDirExists = tdir.mkdir();
  62.                         if (confDirExists && tmpDirExists) {
  63.                             //check the stat file to sanitize the default errors
  64.                             File stat = new File(tmpDir + "/stat");
  65.                             if (!stat.exists()) {
  66.                                 FileWriter statfile = new FileWriter(stat);
  67.                                 statfile.write("");
  68.                                 statfile.close();
  69.                             }
  70.                             //extract the resource in the raw folder into the App private space and overwrite if it already exists
  71.                             String appFileDirectory = getFilesDir().getParent();
  72.                             oscamFilename = appFileDirectory + "/oscam";
  73.                             InputStream ins = getResources().openRawResource(R.raw.oscam);
  74.                             final byte[] buffer = new byte[ins.available()];
  75.                             ins.read(buffer);
  76.                             ins.close();
  77.                             File destination = new File(oscamFilename);
  78.                             if (destination.exists())
  79.                                 destination.delete();
  80.                             FileOutputStream fos = new FileOutputStream(destination);
  81.                             fos.write(buffer);
  82.                             fos.close();
  83.                             if (destination.exists()) {
  84.                                 //set executable rights on the file (chmod)
  85.                                 boolean isExecutable = destination.setExecutable(true);
  86.                                 if (isExecutable) {
  87.                                     setStatus(true, "Launching oscam with confDir='" + confDir + "' and tmpDir='" + tmpDir + "'...");
  88.                                     //start the Oscam process
  89.                                     oscamProcess = new ProcessBuilder().command(oscamFilename, "--config-dir", confDir, "--temp-dir", tmpDir).redirectErrorStream(true).start();
  90.                                     //start a thread to read Oscam logs and print them on our textview
  91.                                     Thread readThread = new Thread(new Runnable() {
  92.                                         @Override
  93.                                         public void run() {
  94.                                             try {
  95.                                                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(oscamProcess.getInputStream()));
  96.                                                 while (!Thread.currentThread().isInterrupted()) {
  97.                                                     if (bufferedReader.ready()) {
  98.                                                         String line = bufferedReader.readLine();
  99.                                                         setStatus(true, line);
  100.                                                     }
  101.                                                 }
  102.                                                 bufferedReader.close();
  103.                                             } catch (Exception e) {
  104.                                                 e.printStackTrace();
  105.                                             }
  106.                                         }
  107.                                     });
  108.                                     readThread.start();
  109.                                     //wait for the process to terminate
  110.                                     oscamProcess.waitFor();
  111.                                     //when we get here, the process is already dead, we should cleanup
  112.                                     readThread.interrupt();
  113.                                     oscamProcess = null;
  114.                                     setStatus(false, "Oscam stopped!");
  115.                                 } else
  116.                                     setStatus(false, "Oscam is not executable!");
  117.                             } else
  118.                                 setStatus(false, "Oscam binary not found!");
  119.                         } else
  120.                             setStatus(false, "Unable to read/write configuration and tmp folder!");
  121.                     } catch (Exception e) {
  122.                         e.printStackTrace();
  123.                     }
  124.                 }
  125.             }).start();
  126.         }
  127.     }

  128.     public void stopOscam(View view){
  129.         if (oscamProcess != null) {
  130.             try {
  131.                 //get the Oscam process PID by using reflection
  132.                 long pid = -1;
  133.                 try {
  134.                     Field f = oscamProcess.getClass().getDeclaredField("pid");
  135.                     f.setAccessible(true);
  136.                     pid = f.getLong(oscamProcess);
  137.                     f.setAccessible(false);
  138.                 } catch (Exception e) {
  139.                     pid = -1;
  140.                 }
  141.                 //send a SIGTERM to the oscam process
  142.                 Runtime.getRuntime().exec("kill -15 " + pid);
  143.             } catch (IOException e) {
  144.                 e.printStackTrace();
  145.             }
  146.         }else
  147.             setStatus(false, "Oscam stopped!");
  148.     }


  149. }
复制代码
7、运行应用程序并单击开始按钮后,你应该看到这样的界面。

就是这样。 你刚做了一个可以启动和停止的Oscam APK。 请记住将您的配置文件放在/ sdcard / oscam /文件夹中,然后就可以开始了。
以上所有代码的示例项目也可以在GitHub上获得。
显然你可以对这个应用程序做更多的改进。 例如,这应该是一个服务,并在启动时运行,不会被系统杀死。
但是,这超出了本教程的范围,您应该查看Android文档以了解更多信息。





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
我的恩山、我的无线 The best wifi forum is right here.
技,技,,,,,,,,技术帖。。
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

感觉很牛的样子
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

二、Building an Oscam APK for Android在上一节中如果已经编译出Oscam二进制文件,那么这一步生成apk的过程无论是Linux系统还是Windows系统都可以完成。
1、使用空白活动创建一个新的Android项目。

应该为:
二、Building an Oscam APK for Android在上一节中如果已经编译出Oscam二进制文件,那么这一步生成apk的过程无论是Linux系统还是Windows系统都可以完成。
1、使用 Android Studio 创建一个新的Android项目。



.

点评

谢谢指正!  详情 回复 发表于 2019-11-7 18:21
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| | 显示全部楼层
高级菜鸟 发表于 2018-5-5 17:41
二、Building an Oscam APK for Android在上一节中如果已经编译出Oscam二进制文件,那么这一步生成apk的过 ...

谢谢指正!
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2024-4-27 20:29

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com 举报电话:0519-86695797

快速回复 返回顶部 返回列表