admin

irobot 的app开发过程中遇见的一些问题总结
最近一直在忙学校的新生杯扫地机器人irobot项目app,现在对开发过程中的一些问题进行总结。一、按钮集群因为Ap...
扫描右侧二维码阅读全文
31
2018/05

irobot 的app开发过程中遇见的一些问题总结

最近一直在忙学校的新生杯扫地机器人irobot项目app,现在对开发过程中的一些问题进行总结。

一、按钮集群

因为App中需要用到较多按钮,固然可以一个一个地设置setOnClickListener,但也可以进行优化,代码如下

Button btn1,btn2;  
btn1 = (Button)findViewById(R.id.btn1);  
btn2 = (Button)findViewById(R.id.btn2);  
View.OnclickListener listener = new OnclickListener(){  
@Override  
public void onClick( View view){  
switch(view.getId()){  
case R.id.btn1:  
Log.d("btn1"," has been clicked! ");  
break;  
case R.id.btn2:  
Log.d("btn2","has been clicked !");  
break;  
default:  
break;   
  }  
 }  
}  
btn1.setOnclickListener(listener);  
btn2.setOnclickListener(listener);

二、按钮外观优化

做的时候我在考虑怎么优化按钮的外观,发现用alpha可以改变按钮的透明度,代码如下:

android:alpha="1.0"  <!-- 在XML中取值为0到1,0为完全透明,1为完全不透明,  
除此之外,可以在用imageView.setAlpha(xxx);来实现(这里xxx的取值范围为0-255)   -->

如何做出别的形状的按钮:

① 可以在Drawable 文件下下创建一个shape 的XML,示例代码如下:

[html] view plain copy
<?xml version="1.0" encoding="utf-8"?>  
<shape xmlns:android="http://schemas.android.com/apk/res/android">  
  
    <solid android:color="#ffff00"/>  
  
    <stroke  
  
        android:width="2dp"  
        android:color="#ff00ff"/>  
  
    <corners  
        android:bottomLeftRadius="20dp"  
        android:bottomRightRadius="20dp"  
        android:topLeftRadius="20dp"  
        android:topRightRadius="20dp"/>  
  
    <gradient  
  
        android:startColor="#ff0000"  
        android:endColor="#ffffff"  
        android:type="radial"  
        android:centerX="0.5"  
        android:centerY="0.5"  
        android:gradientRadius="500dp" />  
  
    <padding  
  
        android:bottom="15dp"  
        android:top="15dp"  
        android:left="15dp"  
        android:right="15dp"  
        />  
  
    </shape>

corners用来设置圆角按钮

gradient设置渐变颜色,有liner,radial等选项,endColor和startColor为渐变的起始和终止渐变颜色

padding为设置文字与四边的间距

stroke为设置边框属性

完成该XML的创建后可以在要创建的Button中用background来设置

android:background="@drawable/button_test"

② 也可以用ImageButton来设置,直接用src来设置想要作为背景的图片

(PS:这边我还遇到了一个小问题,即drawable下放入的图片只能用小写字母,且不能以数字开头)

三、关于如何设置标题栏

我发现app的标题栏在我的app中显得out of place, 于是实现标题栏的隐藏

① 在AndroidManifest中的<activity>下设置:

android:theme="@android:style/Theme.Holo.NoActionBar"

②在Java Class 中调用actionbar的hide方法

(第一行代码上的方法就是这个,进一步可以用back键绑定((Activity) getContext().finish();)来实现返回效果  )

 

如果想实现自定义的标题栏,新建XML(绑定事件的话再新建java class) 然后在布局中inflate

四、引入自定义字体的方法:

1、在网上下载字体文件(.ttf),并在工程目录的./main下,新建assets/fonts文件夹,并把.ttf文件放入其

中,如图

当然,如果不想在网上下载的话,就在C:\Windows\fonts下寻找对应的.ttf文件

2、在想要应用自定义字体的Activity Class中引入对应字体,代码如下:

@Override  
   protected void onCreate(Bundle savedInstanceState) {  
       super.onCreate(savedInstanceState);  
       setContentView(R.layout.activity_main);  
       final TextView textView;  
       textView = (TextView) findViewById(R.id.textview1);  
       Typeface typeface = Typeface.createFromAsset(getAssets(),"fonts/LHANDW.TTF");  
       textView.setTypeface(typeface);  
       if (savedInstanceState == null) {  
           FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();  
           BluetoothChatFragment fragment = new BluetoothChatFragment();  
           transaction.replace(R.id.sample_content_fragment, fragment);  
           transaction.commit();  
       }  
   }

这里只在TextView 中加载了对应字体

五、调整ProgressBar的外观:

final ProgressDialog progressDialog = new ProgressDialog(Welcome.this);  

        progressDialog.setMessage("Loading...");  
        progressDialog.setCancelable(false);  
        progressDialog.show();  
        Point size = new Point();  
        progressDialog.getWindow().getWindowManager().
    getDefaultDisplay().getSize(size);  //一定要用progressDialog去得到 
 
        int width = size.x;  
        int height = size.y;  
        WindowManager.LayoutParams params = progressDialog.getWindow().getAttributes();  
        params.alpha = 1.0f;    //设置进度条透明度  
        params.height = height/8;   //设置进度条高度  
        params.gravity = Gravity.CENTER; 
        params.width = 4*width/5;  
        params.dimAmount = 0f;   //设置半透明背景的灰度

 

六、关于用iRobot播放音乐

关键问题是得到音乐文件的二进制编码,由于下载的MP3或者MP4文件就是二进制的,这里直接用UltraEdit

打开就行。当然,考虑到MP4文件过大,而这里我们不需要那么好的播放效果,可以用.midi格式替代,大小只有

十几或者几十KB,却能包含数十条音

轨,这里截了一个关于百度百科对midi格式的说明,如下图:

七、蓝牙的连接

这个项目的核心问题就是要实现手机端与irobot上蓝牙模块的连接,这里我是下载的Github上的源码。结果发现连接不上。

一开始我以为是PIN码问题,后来发现不是,PIN码是用来实现配对的,这个配对可以在Android 手机中的Settings内完成,默认

的PIN码是1234或0000。而我是连接失败,这个连接问题一般是UUID问题。

UUID是设备的唯一识别码,由三部分组成,当前的日期和时间、时钟序列、全球唯一的IEEE设备识别号,如果有网卡,从

网卡MAC地址获得。UUID一般会比较长,对此使用比较广泛的是微软的GUID,在JAVA中可以用以下代码生成

import java.util.UUID;  
   public class Test {  
      public static void main(String[] args) {  
        UUID uuid = UUID.randomUUID();   
        System.out.println (uuid);  
      }  
   }

扯远了,我后来把源代码中的UUID修改了一下,发现竟然连接上了!具体原理大概是蓝牙串口通信或是不同的通信服务

需要特定的UUID吧,这里附上一个链接参考:https://blog.csdn.net/spmno/article/details/6931941

private static final UUID MY_UUID_SECURE =  
        //UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");  
        UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  
private static final UUID MY_UUID_INSECURE =  
        //UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");  
        UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

八、生成正式的.apk

注意如果res目录下的文件不是.png格式的就会出错,如果都是.png还是无法生成的话,可以试试删除图片重新下载或者

invalidate cache

九、Rockerview的引入

为了增强操作性,我通过引入第三方库另增了一个虚拟摇杆界面,可以在手指触摸的时候显示机器人前进的方向和速度值。

如图所示

十、横屏显示

因为这里我用了虚拟摇杆和几个按键组成的界面,横屏显示会更美观。步骤如下:

 

在res目录下新建resource file  ,导入orientation, 并选择Landscape(landscape为横屏,portrait为纵向显示)

然后修改对应的Activity中的setcontentview即可,如图

十一、引入重力传感器

也是为了让我这个巨丑的界面显得更加酷炫,我加了个重力传感器,代码如下:

sensorManager =(SensorManager) getSystemService(Context.SENSOR_SERVICE);  
  
        Sensor accelerometersensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);  
        Sensor magneticsensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);  
        sensorManager.registerListener(listener,accelerometersensor,SensorManager.SENSOR_DELAY_GAME);  
        
sensorManager.registerListener(listener,magneticsensor,SensorManager.SENSOR_DELAY_GAME);  
@Override  
   protected void onDestroy() {  
       super.onDestroy();  
       if(sensorManager!=null){  
           sensorManager.unregisterListener(listener);  
       }  
   }  
  
   private SensorEventListener listener = new SensorEventListener() {  
  
       float[] accelerometerValues = new float[3];  
       float[] magneticValues = new float[3];  
  
       @Override  
       public void onSensorChanged(SensorEvent event) {  
           // 判断当前是加速度传感器还是地磁传感器  
           if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {  
               // 注意赋值时要调用clone()方法  
               accelerometerValues = event.values.clone();  
           } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {  
               // 注意赋值时要调用clone()方法  
               magneticValues = event.values.clone(); }  
               float[] R = new float[9];  
               float[] values = new float[3];  
               SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticValues);  
               SensorManager.getOrientation(R, values);  
               Log.d("MainActivity", "value[0] is " + Math.toDegrees(values[0]));  
           }  
  
  
       @Override  
       public void onAccuracyChanged(Sensor sensor, int accuracy) {  
  
       }  
   };

这里采用的是加速度传感器和磁力传感器,代码我也是看的郭神的《第一行代码》上的。然后在Androidmanifest文件中加入以下支持:

<uses-permission android:name="android.permission.BODY_SENSORS"/>

表示加入传感器的权限,接着再在安卓手机的设置界面里找到权限,给对应app开启身体传感器权限。这里要注意如果不先在Androidmanifest 中加入对应支持,是无法在app中找到对应权限的。

项目代码:https://github.com/550517968/iRobot

Last modification:March 13th, 2019 at 07:06 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment