TabLayout + ViewPager + Fragment + 百度地图 + 传感器 + 自定义View + AIDL
目录结构
导入依赖 -- 自己搜索
compile 'com.android.support:design:26.0.0-alpha1'
在百度开发平台上, 申请 AK
导入百度需要的jar包 和 so包 , 到libs 中
jar 包关联到工程中 -- 右键 -- Add as library
so包关联在工程中 -- 需要在 build.gradle中 adnroid {} 内部 添加
sourceSets{ main(){ jniLibs.srcDir 'libs' //说明so的路径为该libs路径,关联所有地图SDK的so文件 } }
所有页面:
activity_main.java
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="match_parent" tools:context="bw.com.app2.MainActivity"> <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="60dp" android:id="@+id/tl_id" /> <android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/vp_id" /> </LinearLayout>
my_fragment01.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="bw.com.app2.MyFragment01"> <com.baidu.mapapi.map.MapView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/map_view_id"/> </FrameLayout>
my_fragment02.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/shakehideimg_man2" android:layout_centerInParent="true" android:id="@+id/flower_id"/> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/shake_logo_up" android:id="@+id/shake_up_id"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/shake_logo_down" android:id="@+id/shake_down_id"/> </LinearLayout> </RelativeLayout>
my_fragment03.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="bw.com.app2.MyFragment03"> <bw.com.app2.CustomView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/cs_id" /> </FrameLayout>
my_fragment04.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="bw.com.app2.MyFragment04"> <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tv_id" android:text="@string/hello_blank_fragment" /> </FrameLayout>
代码
MyApp.java
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); //初始化地图 SDKInitializer.initialize(getApplicationContext()); } }在清单文件中, 添加内容
百度地图权限 + 震动权限 + 百度地图的ak -- 如果是定位, 参考博客中的其他文章
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> //获取设备网络状态,禁用后无法获取网络状态 <uses-permission android:name="android.permission.INTERNET"/> //网络权限,当禁用后,无法进行检索等相关业务 <uses-permission android:name="android.permission.READ_PHONE_STATE" /> //读取设备硬件信息,统计数据 <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> //读取系统信息,包含系统版本等信息,用作统计 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> //获取设备的网络状态,鉴权所需网络代理 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> //允许sd卡写权限,需写入地图数据,禁用后无法显示地图 <uses-permission android:name="android.permission.WRITE_SETTINGS" /> //获取统计数据 <uses-permission android:name="android.permission.GET_TASKS" /> //鉴权所需该权限获取进程列表 <uses-permission android:name="android.permission.CAMERA" /> //使用步行AR导航,配置Camera权限 <!--震动的权限--> <uses-permission android:name="android.permission.VIBRATE"/>
<application android:name=".MyApp" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="d5arqAnLx1HsD4AXIk3nwlM4ZRqmT80P" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
MainActivity.java
public class MainActivity extends AppCompatActivity { private ViewPager mVp; private List<Fragment> data; private MyAdapter adapter; private TabLayout mTl; private List<String> titles = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mVp = (ViewPager) findViewById(R.id.vp_id); mTl = (TabLayout) findViewById(R.id.tl_id); //初始化数据源 data = new ArrayList<>(); data.add(new MyFragment01()); data.add(new MyFragment02()); data.add(new MyFragment03()); data.add(new MyFragment04()); //初始化标题 titles.add("地图"); titles.add("传感器"); titles.add("饼图"); titles.add("AIDL"); adapter = new MyAdapter(getSupportFragmentManager()); mVp.setAdapter(adapter); //将TabLayout和ViewPager 关联在一起 mTl.setupWithViewPager(mVp); } class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return data.get(position); } @Override public int getCount() { return data.size(); } //设置导航图标 @Override public CharSequence getPageTitle(int position) { return titles.get(position) ; } } }
MyFragment01.java
public class MyFragment01 extends Fragment { private MapView mMapView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.my_fragment01, container, false); mMapView = (MapView) view.findViewById(R.id.map_view_id); return view; } @Override public void onDestroy() { super.onDestroy(); mMapView.onDestroy(); } @Override public void onResume() { super.onResume(); mMapView.onResume(); } @Override public void onPause() { super.onPause(); mMapView.onPause(); } }
MyFragment02.java
public class MyFragment02 extends Fragment implements SensorEventListener { private ImageView mShakeUp; private ImageView mShakeDown; //动画 private TranslateAnimation animationUp; private TranslateAnimation animationDown; private SensorManager manager; //震动管理器 private Vibrator vibrator; //添加声音 private SoundPool soundPool;//声音池 private int mLoadId;//当前加载的声音 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.my_fragment02, container, false); mShakeUp = (ImageView) view.findViewById(R.id.shake_up_id); mShakeDown = (ImageView) view.findViewById(R.id.shake_down_id); //得到传感器的管理器对象 manager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); //初始化震动管理器 vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); //初始化声音 //最大数量,类型,质量 默认0 soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC,0); mLoadId = soundPool.load(getContext(),R.raw.awe,1); //初始化动画 initAnimation(); return view; } //注册传感器 @Override public void onResume() { super.onResume(); // SensorManager.SENSOR_DELAY_FASTEST; // SensorManager.SENSOR_DELAY_GAME; // SensorManager.SENSOR_DELAY_NORMAL; // SensorManager.SENSOR_DELAY_UI; manager.registerListener(this,manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),200); } //取消注册 @Override public void onPause() { super.onPause(); manager.unregisterListener(this); } //--- 监听器的回调方法 ------ @Override public void onSensorChanged(SensorEvent event) { float[] data = event.values; if(Math.abs(data[0])>12 || Math.abs(data[1]) > 12 || Math.abs(data[2])>12) { //添加震动 -- 需要添加权限 long[] pattern = {300,500}; vibrator.vibrate(pattern,-1); //播放声音 //声音的id, 左声道的音量(0.0--1.0), 由声道的音量, 优先级, 是否循环播放(0 不循环, -1 循环), 播放的比例(1 正常播放) soundPool.play(mLoadId,1.0f,1.0f,1,0,1.0f); //启动动画 mShakeUp.startAnimation(animationUp); mShakeDown.startAnimation(animationDown); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } //动画的初始化方法 public void initAnimation() { //补间动画 -- 位移 animationUp = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0, Animation.RELATIVE_TO_SELF,0, Animation.RELATIVE_TO_SELF,0, Animation.RELATIVE_TO_SELF,-1 ); animationUp.setDuration(3000); animationDown = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0, Animation.RELATIVE_TO_SELF,0, Animation.RELATIVE_TO_SELF,0, Animation.RELATIVE_TO_SELF,1 ); animationDown.setDuration(3000); } }
MyFragment03.java
public class MyFragment03 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.my_fragment03, container, false); } }
CustomView.java
public class CustomView extends View { private Paint paint; public CustomView(Context context) { super(context); } public CustomView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); paint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //外轮廓矩形 RectF rectF = new RectF(0,0,500,500); //绘制第一个扇形 paint.setColor(Color.RED); canvas.drawArc(rectF,0,90,true,paint); //绘制背景 paint.setColor(Color.BLACK); canvas.drawRect(330,320,430,370,paint); //绘制第一个文字 paint.setColor(Color.WHITE); paint.setTextSize(30); canvas.drawText("90%",350,350,paint); //绘制第二个扇形 paint.setColor(Color.CYAN); canvas.drawArc(rectF,90,110,true,paint); //绘制背景 paint.setColor(Color.BLACK); canvas.drawRect(100,320,200,370,paint); paint.setColor(Color.WHITE); paint.setTextSize(30); canvas.drawText("110%",120,350,paint); //绘制第三个扇形 paint.setColor(Color.BLUE); canvas.drawArc(rectF,200,90,true,paint); //绘制背景 paint.setColor(Color.BLACK); canvas.drawRect(120,100,220,150,paint); paint.setColor(Color.WHITE); paint.setTextSize(30); canvas.drawText("90%",150,150,paint); //绘制第四个扇形 paint.setColor(Color.GRAY); canvas.drawArc(rectF,290,70,true,paint); //绘制背景 paint.setColor(Color.BLACK); canvas.drawRect(350,120,450,170,paint); paint.setColor(Color.WHITE); paint.setTextSize(30); canvas.drawText("70%",350,150,paint); //绘制中间的圆 paint.setColor(Color.GREEN); canvas.drawCircle(250,250,50,paint); paint.setColor(Color.WHITE); paint.setTextSize(30); canvas.drawText("center",220,260,paint); } }
MyFragment04.java -- 需要一个服务器, 所有需要再次创建一个 Server 工程
public class MyFragment04 extends Fragment { private DBAidl dataAidl;//Aidl 文件 private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { dataAidl = DBAidl.Stub.asInterface(service); try { //获取服务端的数据 String str = dataAidl.getDbInfo(); mTv.setText(str); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; private TextView mTv; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.my_fragment04, container, false); mTv = (TextView) view.findViewById(R.id.tv_id); return view; } //绑定服务 @Override public void onStart() { super.onStart(); Intent intent = new Intent("com.bw.aidl.db"); intent.setPackage("bw.com.server"); getContext().bindService(intent,connection,BIND_AUTO_CREATE); } //解绑服务 @Override public void onStop() { super.onStop(); getContext().unbindService(connection); } }
在src/main 中, 将服务端工程中的aidl 文件夹复制过来, 放到同级的目录下
Server 服务器端
在src/main 中 右键创建一个aidl 文件
DBAidl.aidl
interface DBAidl { //返回数据库中的所有信息 String getDbInfo(); }
编译工程 生成同名的.java 文件
MainActivity.java
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
MyService.java
public class MyService extends Service { DBAidl.Stub stub = new DBAidl.Stub() { @Override public String getDbInfo() throws RemoteException { //获取数据库中的内容, 并且返回 DbOpenHelper openHelper = new DbOpenHelper(getApplicationContext()); SQLiteDatabase db = openHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("select * from user",null); StringBuilder sBuilder = new StringBuilder(); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex("uName")); String pwd = cursor.getString(cursor.getColumnIndex("uPwd")); sBuilder.append("name = " + name +", pwd = "+ pwd).append("\n"); } return sBuilder.toString(); } }; @Nullable @Override public IBinder onBind(Intent intent) { return stub; } }
DbOpenHelper.java
public class DbOpenHelper extends SQLiteOpenHelper { public DbOpenHelper(Context context) { super(context, "1511A.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table if not exists user(_id integer primary key autoincrement, uName,uPwd)"); db.execSQL("insert into user(uName,uPwd) values('张三','123')"); db.execSQL("insert into user(uName,uPwd) values('李四','123')"); db.execSQL("insert into user(uName,uPwd) values('王五','123')"); db.execSQL("insert into user(uName,uPwd) values('赵六','123')"); db.execSQL("insert into user(uName,uPwd) values('田七','123')"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
清单文件中, 注册Service
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="bw.com.server"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService"> <intent-filter> <action android:name="com.bw.aidl.db"/> </intent-filter> </service> </application>