目录

概述

一、运行环境:

二、编码

三、结果

四、总结


概述

由于最近有个地磁项目的需要,重温多年Android知识,通过手机地磁传感器数据,编写了一个指南针App。

一、运行环境:

1、小米手机 MIUI版本 12.5.4

2、Android Studio Arctic Fox | 2020.3.1


二、编码

1、创建MiCompass.java文件(自定义view)

package com.example.mycompass;import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Matrix;
import android.graphics.Camera;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Color;
import android.graphics.RadialGradient;
import android.view.MotionEvent;
import android.view.View;import androidx.annotation.Nullable;
import android.util.AttributeSet;public class MiCompass extends View{private Canvas mCanvas;private Context mContext;//View矩形的宽度private int width;//指南针圆心点坐标private int mCenterX;private int mCenterY;//外圆半径private int mOutSideRadius;//外接圆半径private int mCircumRadius;//指南针文字大小空间高度private int mTextHeight;//暗红色 外圈笔private Paint mDarkRedPaint;//深灰 外圈笔private Paint mDeepGrayPaint;//外三角笔private Paint mOutSideCircumPaint;//浅灰 外圈笔private Paint mLightGrayPaint;//指南针上面 文字笔private Paint mTextPaint;//外接圆,三角形笔private Paint mCircumPaint;//指南针上面文字的外接矩形,用来测文字大小让文字居中private Rect mTextRect;//外圈小三角形的Pathprivate Path mOutsideTriangle;//外接圆小三角形的Pathprivate Path mCircumTriangle;//NESW 文字笔 和文字外接矩形private Paint mNorthPaint;private Paint mOthersPaint;private Rect  mPositionRect;//小刻度文字大小矩形和画笔private Paint mSamllDegreePaint;//两位数的private Rect mSencondRect;//三位数的private Rect mThirdRect;//圆心数字矩形private Rect mCenterTextRect;//中心文字笔private Paint mCenterPaint;//内心圆是一个颜色辐射渐变的圆private Shader mInnerShader;private Paint mInnerPaint;//定义个点击属性动画private ValueAnimator mValueAnimator;// camera绕X轴旋转的角度private float mCameraRotateX;// camera绕Y轴旋转的角度private float mCameraRotateY;//camera最大旋转角度private float mMaxCameraRotate = 10;// camera绕X轴旋转的角度private float mCameraTranslateX;// camera绕Y轴旋转的角度private float mCameraTranslateY;//camera最大旋转角度private float mMaxCameraTranslate;//camera矩阵private Matrix mCameraMatrix;//设置cameraprivate Camera mCamera;private float val=0f;private float valCompare;//偏转角度红线笔private Paint mAnglePaint;//方位文字private String text="北";public float getVal() {return val;}public void setVal(float val) {this.val = val;invalidate();}public MiCompass(Context context) {this(context,null);}public MiCompass(Context context, @Nullable AttributeSet attrs) {this(context, attrs,0);}public MiCompass(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;mDarkRedPaint = new Paint();mDarkRedPaint.setStyle(Paint.Style.STROKE);mDarkRedPaint.setAntiAlias(true);mDarkRedPaint.setColor(context.getResources().getColor(R.color.darkRed));mDeepGrayPaint = new Paint();mDeepGrayPaint.setStyle(Paint.Style.STROKE);mDeepGrayPaint.setAntiAlias(true);mDeepGrayPaint.setColor(context.getResources().getColor(R.color.deepGray));mLightGrayPaint = new Paint();mLightGrayPaint.setStyle(Paint.Style.FILL);mLightGrayPaint.setAntiAlias(true);mLightGrayPaint.setColor(context.getResources().getColor(R.color.lightGray));mTextPaint = new Paint();mTextPaint.setStyle(Paint.Style.STROKE);mTextPaint.setAntiAlias(true);mTextPaint.setTextSize(80);mTextPaint.setColor(context.getResources().getColor(R.color.white));mCircumPaint = new Paint();mCircumPaint.setStyle(Paint.Style.FILL);mCircumPaint.setAntiAlias(true);mCircumPaint.setColor(context.getResources().getColor(R.color.red));mOutSideCircumPaint = new Paint();mOutSideCircumPaint.setStyle(Paint.Style.FILL);mOutSideCircumPaint.setAntiAlias(true);mOutSideCircumPaint.setColor(context.getResources().getColor(R.color.lightGray));mTextRect = new Rect();mOutsideTriangle = new Path();mCircumTriangle = new Path();mNorthPaint = new Paint();mNorthPaint.setStyle(Paint.Style.STROKE);mNorthPaint.setAntiAlias(true);mNorthPaint.setTextSize(40);mNorthPaint.setColor(context.getResources().getColor(R.color.red));mOthersPaint = new Paint();mOthersPaint.setStyle(Paint.Style.STROKE);mOthersPaint.setAntiAlias(true);mOthersPaint.setTextSize(40);mOthersPaint.setColor(context.getResources().getColor(R.color.white));mPositionRect = new Rect();mCenterTextRect = new Rect();mCenterPaint = new Paint();mCenterPaint.setStyle(Paint.Style.STROKE);mCenterPaint.setAntiAlias(true);mCenterPaint.setTextSize(120);mCenterPaint.setColor(context.getResources().getColor(R.color.white));mSamllDegreePaint = new Paint();mSamllDegreePaint.setStyle(Paint.Style.STROKE);mSamllDegreePaint.setAntiAlias(true);mSamllDegreePaint.setTextSize(30);mSamllDegreePaint.setColor(context.getResources().getColor(R.color.lightGray));mSencondRect = new Rect();mThirdRect = new Rect();mInnerPaint = new Paint();mInnerPaint.setStyle(Paint.Style.FILL);mInnerPaint.setAntiAlias(true);mAnglePaint = new Paint();mAnglePaint.setStyle(Paint.Style.STROKE);mAnglePaint.setAntiAlias(true);mAnglePaint.setColor(context.getResources().getColor(R.color.red));mCameraMatrix = new Matrix();mCamera = new Camera();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mCanvas = canvas;//设置Camera矩阵 实现3D效果set3DMetrix();//画文字drawText();//画指南针外圈drawCompassOutSide();//画指南针外接圆drawCompassCircum();//画内部渐变颜色圆drawInnerCricle();//画指南针内部刻度drawCompassDegreeScale();//画圆心数字drawCenterText();}/*** 设置camera相关*/private void set3DMetrix() {mCameraMatrix.reset();mCamera.save();mCamera.rotateX(mCameraRotateX);mCamera.rotateY(mCameraRotateY);mCamera.getMatrix(mCameraMatrix);mCamera.restore();//camera默认旋转是View左上角为旋转中心//所以动作之前要,设置矩阵位置 -mTextHeight-mOutSideRadiusmCameraMatrix.preTranslate(-getWidth()/2,-getHeight()/2);//动作之后恢复位置mCameraMatrix.postTranslate(getWidth()/2,getHeight()/2);mCanvas.concat(mCameraMatrix);}private void drawInnerCricle() {mInnerShader = new RadialGradient(width/2,mOutSideRadius+mTextHeight,mCircumRadius-40, Color.parseColor("#323232"),Color.parseColor("#000000"),Shader.TileMode.CLAMP);mInnerPaint.setShader(mInnerShader);mCanvas.drawCircle(width/2,mOutSideRadius+mTextHeight,mCircumRadius-40,mInnerPaint);}private void drawCenterText() {String centerText=String.valueOf((int) val+"°");mCenterPaint.getTextBounds(centerText,0,centerText.length(),mCenterTextRect);int centerTextWidth = mCenterTextRect.width();int centerTextHeight = mCenterTextRect.height();mCanvas.drawText(centerText,width/2-centerTextWidth/2,mTextHeight+mOutSideRadius+centerTextHeight/5,mCenterPaint);}private void drawCompassDegreeScale() {mCanvas.save();//获取N文字的宽度mNorthPaint.getTextBounds("N",0,1,mPositionRect);int mPositionTextWidth = mPositionRect.width();int mPositionTextHeight = mPositionRect.height();//获取W文字宽度,因为W比较宽 所以要单独获取mNorthPaint.getTextBounds("W",0,1,mPositionRect);int mWPositionTextWidth = mPositionRect.width();int mWPositionTextHeight = mPositionRect.height();//获取小刻度,两位数的宽度mSamllDegreePaint.getTextBounds("30",0,1,mSencondRect);int mSencondTextWidth = mSencondRect.width();int mSencondTextHeight = mSencondRect.height();//获取小刻度,3位数的宽度mSamllDegreePaint.getTextBounds("30",0,1,mThirdRect);int mThirdTextWidth = mThirdRect.width();int mThirdTextHeight = mThirdRect.height();mCanvas.rotate(-val,width/2,mOutSideRadius+mTextHeight);//画刻度线for (int i = 0; i < 240; i++) {if (i==0||i==60||i==120||i==180){mCanvas.drawLine(getWidth() / 2, mTextHeight+mOutSideRadius-mCircumRadius+10,getWidth() / 2,  mTextHeight+mOutSideRadius-mCircumRadius+30, mDeepGrayPaint);}else{mCanvas.drawLine(getWidth() / 2, mTextHeight+mOutSideRadius-mCircumRadius+10,getWidth() / 2,  mTextHeight+mOutSideRadius-mCircumRadius+30, mLightGrayPaint);}if (i==0){mCanvas.drawText("N", this.width /2-mPositionTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mPositionTextHeight,mNorthPaint);}else if (i==60){mCanvas.drawText("E", this.width /2-mPositionTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mPositionTextHeight,mOthersPaint);}else if (i==120){mCanvas.drawText("S", this.width /2-mPositionTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mPositionTextHeight,mOthersPaint);}else if (i==180){mCanvas.drawText("W", this.width /2-mWPositionTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mWPositionTextHeight,mOthersPaint);}else if (i==20){mCanvas.drawText("30", this.width /2-mSencondTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mSencondTextHeight,mSamllDegreePaint);}else if (i==40){mCanvas.drawText("60", this.width /2-mSencondTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mSencondTextHeight,mSamllDegreePaint);}else if (i==80){mCanvas.drawText("120", this.width /2-mThirdTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mThirdTextHeight,mSamllDegreePaint);}else if (i==100){mCanvas.drawText("150", this.width /2-mThirdTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mThirdTextHeight,mSamllDegreePaint);}else if (i==140){mCanvas.drawText("210", this.width /2-mThirdTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mThirdTextHeight,mSamllDegreePaint);}else if (i==160){mCanvas.drawText("240", this.width /2-mThirdTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mThirdTextHeight,mSamllDegreePaint);}else if (i==200){mCanvas.drawText("300", this.width /2-mThirdTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mThirdTextHeight,mSamllDegreePaint);}else if (i==220){mCanvas.drawText("330", this.width /2-mThirdTextWidth/2,mTextHeight+mOutSideRadius-mCircumRadius+40+mThirdTextHeight,mSamllDegreePaint);}mCanvas.rotate(1.5f, mCenterX, mOutSideRadius+mTextHeight);}mCanvas.restore();}/*** 指南针外接圆,和外部圆换道理差不多*/private void drawCompassCircum() {mCanvas.save();//外接圆小三角形的高度int mTriangleHeight=(mOutSideRadius-mCircumRadius)/2;mCanvas.rotate(-val,width/2,mOutSideRadius+mTextHeight);mCircumTriangle.moveTo(width/2,mTriangleHeight+mTextHeight);//内接三角形的边长,简单数学运算float mTriangleSide = (float) ((mTriangleHeight/(Math.sqrt(3)))*2);mCircumTriangle.lineTo(width/2-mTriangleSide/2,mTextHeight+mTriangleHeight*2);mCircumTriangle.lineTo(width/2+mTriangleSide/2,mTextHeight+mTriangleHeight*2);mCircumTriangle.close();mCanvas.drawPath(mCircumTriangle,mCircumPaint);mCanvas.drawArc(width/2-mCircumRadius,mTextHeight+mOutSideRadius-mCircumRadius,width/2+mCircumRadius,mTextHeight+mOutSideRadius+mCircumRadius,-85,350,false,mDeepGrayPaint);mAnglePaint.setStrokeWidth(5f);if (val<=180){valCompare = val;mCanvas.drawArc(width/2-mCircumRadius,mTextHeight+mOutSideRadius-mCircumRadius,width/2+mCircumRadius,mTextHeight+mOutSideRadius+mCircumRadius,-85,valCompare,false,mAnglePaint);}else{valCompare = 360-val;mCanvas.drawArc(width/2-mCircumRadius,mTextHeight+mOutSideRadius-mCircumRadius,width/2+mCircumRadius,mTextHeight+mOutSideRadius+mCircumRadius,-95,-valCompare,false,mAnglePaint);}mCanvas.restore();}/*** 指南针外部可简单分为两部分* 1、用Path实现小三角形* 2、两个圆弧*/private void drawCompassOutSide() {mCanvas.save();//小三角形的高度int mTriangleHeight=40;//定义Path画小三角形mOutsideTriangle.moveTo(width/2,mTextHeight-mTriangleHeight);//小三角形的边长float mTriangleSide = 46.18f;//画出小三角形mOutsideTriangle.lineTo(width/2-mTriangleSide/2,mTextHeight);mOutsideTriangle.lineTo(width/2+mTriangleSide/2,mTextHeight);mOutsideTriangle.close();mCanvas.drawPath(mOutsideTriangle,mOutSideCircumPaint);//画圆弧mDarkRedPaint.setStrokeWidth((float) 5);mLightGrayPaint.setStrokeWidth((float)5);mDeepGrayPaint.setStrokeWidth((float)3);mLightGrayPaint.setStyle(Paint.Style.STROKE);mCanvas.drawArc(width/2-mOutSideRadius,mTextHeight,width/2+mOutSideRadius,mTextHeight+mOutSideRadius*2,-80,120,false,mLightGrayPaint);mCanvas.drawArc(width/2-mOutSideRadius,mTextHeight,width/2+mOutSideRadius,mTextHeight+mOutSideRadius*2,40,20,false,mDeepGrayPaint);mCanvas.drawArc(width/2-mOutSideRadius,mTextHeight,width/2+mOutSideRadius,mTextHeight+mOutSideRadius*2,-100,-20,false,mLightGrayPaint);mCanvas.drawArc(width/2-mOutSideRadius,mTextHeight,width/2+mOutSideRadius,mTextHeight+mOutSideRadius*2,-120,-120,false,mDarkRedPaint);mCanvas.restore();}private void drawText() {if (val<=15||val>=345){text = "北";}else if (val>15&&val<=75){text= "东北";}else if (val>75&&val<=105){text= "东";}else if (val>105&&val<=165){text="东南";}else if (val>165&&val<=195){text = "南";}else if (val>195&&val<=255){text = "西南";}else if (val>255&&val<=285){text = "西";}else if (val>285&&val<345){text="西北";}mTextPaint.getTextBounds(text,0,text.length(),mTextRect);//文字宽度int mTextWidth = mTextRect.width();//让文字水平居中显示mCanvas.drawText(text,width/2-mTextWidth/2,mTextHeight/2,mTextPaint);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);width = Math.min(widthSize, heightSize);if (widthMode == MeasureSpec.UNSPECIFIED) {width = heightSize;} else if (heightMode == MeasureSpec.UNSPECIFIED) {width = widthSize;}//为指南针上面的文字预留空间,定为1/3边张mTextHeight = width/3;//设置圆心点坐标mCenterX = width/2;mCenterY = width/2+mTextHeight;//外部圆的外径mOutSideRadius = width*3/8;//外接圆的半径mCircumRadius = mOutSideRadius*4/5;//camera最大平移距离mMaxCameraTranslate = 0.02f*mOutSideRadius;setMeasuredDimension(width, width+width/3 );}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()){case MotionEvent.ACTION_DOWN:if (mValueAnimator!=null&&mValueAnimator.isRunning()){mValueAnimator.cancel();}//3D 效果让Camera旋转,获取旋转偏移大小getCameraRotate(event);//获取平移大小getCameraTranslate(event);break;case MotionEvent.ACTION_MOVE://3D 效果让Camera旋转,获取旋转偏移大小getCameraRotate(event);//获取平移大小getCameraTranslate(event);break;case MotionEvent.ACTION_UP://松开手 复原动画startRestore();break;}return true;}private void startRestore() {final String cameraRotateXName = "cameraRotateX";final String cameraRotateYName = "cameraRotateY";final String canvasTranslateXName = "canvasTranslateX";final String canvasTranslateYName = "canvasTranslateY";PropertyValuesHolder cameraRotateXHolder =PropertyValuesHolder.ofFloat(cameraRotateXName, mCameraRotateX, 0);PropertyValuesHolder cameraRotateYHolder =PropertyValuesHolder.ofFloat(cameraRotateYName, mCameraRotateY, 0);PropertyValuesHolder canvasTranslateXHolder =PropertyValuesHolder.ofFloat(canvasTranslateXName, mCameraTranslateX, 0);PropertyValuesHolder canvasTranslateYHolder =PropertyValuesHolder.ofFloat(canvasTranslateYName, mCameraTranslateY, 0);mValueAnimator = ValueAnimator.ofPropertyValuesHolder(cameraRotateXHolder,cameraRotateYHolder, canvasTranslateXHolder, canvasTranslateYHolder);mValueAnimator.setInterpolator(new TimeInterpolator() {@Overridepublic float getInterpolation(float input) {float f = 0.571429f;return (float) (Math.pow(2, -2 * input) * Math.sin((input - f / 4) * (2 * Math.PI) / f) + 1);}});mValueAnimator.setDuration(1000);mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mCameraRotateX = (float) animation.getAnimatedValue(cameraRotateXName);mCameraRotateY = (float) animation.getAnimatedValue(cameraRotateYName);mCameraTranslateX = (float) animation.getAnimatedValue(canvasTranslateXName);mCameraTranslateX = (float) animation.getAnimatedValue(canvasTranslateYName);}});mValueAnimator.start();}/*** 获取Camera,平移大小* @param event*/private void getCameraTranslate(MotionEvent event) {float translateX = (event.getX() - getWidth() / 2);float translateY = (event.getY() - getHeight()/2);//求出此时位移的大小与半径之比float[] percentArr = getPercent(translateX, translateY);//最终位移的大小按比例匀称改变mCameraTranslateX = percentArr[0] * mMaxCameraTranslate;mCameraTranslateY = percentArr[1] * mMaxCameraTranslate;}/*** 让Camera旋转,获取旋转偏移大小* @param event*/private void getCameraRotate(MotionEvent event) {float mRotateX = -(event.getY()-(getHeight())/2);float mRotateY = (event.getX()-getWidth()/2);//求出旋转大小与半径之比float[] percentArr = getPercent(mRotateX,mRotateY);mCameraRotateX = percentArr[0]*mMaxCameraRotate;mCameraRotateY = percentArr[1]*mMaxCameraRotate;}/*** 获取比例* @param mCameraRotateX* @param mCameraRotateY* @return*/private float[] getPercent(float mCameraRotateX, float mCameraRotateY) {float[] percentArr = new float[2];float percentX = mCameraRotateX/width;float percentY = mCameraRotateY/width;//处理一下比例值if (percentX > 1) {percentX = 1;} else if (percentX < -1) {percentX = -1;}if (percentY > 1) {percentY = 1;} else if (percentY < -1) {percentY = -1;}percentArr[0] = percentX;percentArr[1] = percentY;return percentArr;}}

2、colors.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources><color name="colorPrimary">#3F51B5</color><color name="colorPrimaryDark">#303F9F</color><color name="colorAccent">#FF4081</color><color name="black">#000</color><color name="darkRed">#702216</color><color name="lightGray">#323232</color><color name="deepGray">#8B8B8B</color><color name="white">#fff</color><color name="red">#f00</color><color name="ocbg">#237EAD</color>
</resources>

3、value\themes.xml、value-nigth\themes.xml文件

此时有两个报错,不用怕,挨个解决,挨个创建即可。

 

报错的地方,按照以上方法,挨个创建即可,创建好之后如下所示:

4、activity_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"android:background="@color/black"tools:context=".MainActivity"><com.example.mycompass.MiCompassandroid:id="@+id/miui"android:layout_centerInParent="true"android:layout_gravity="center"android:background="@color/black"android:layout_width="match_parent"android:layout_height="wrap_content"tools:ignore="MissingConstraints" /></androidx.constraintlayout.widget.ConstraintLayout>

5、MainActivity.java文件

package com.example.mycompass;import androidx.appcompat.app.AppCompatActivity;import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;public class MainActivity extends AppCompatActivity {private SensorManager sensorManager;private SensorEventListener sensorEventListener;private MiCompass miui;private  float val;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);miui = findViewById(R.id.miui);sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);sensorEventListener = new SensorEventListener() {@Overridepublic void onSensorChanged(SensorEvent sensorEvent) {val = sensorEvent.values[0];System.out.println(val);miui.setVal(val);}@Overridepublic void onAccuracyChanged(Sensor sensor, int i) {}};
//        sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)
//        ,sensorManager.SENSOR_DELAY_GAME);sensorManager.registerListener(sensorEventListener,sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onDestroy() {super.onDestroy();sensorManager.unregisterListener(sensorEventListener);}
}

三、结果

四、总结

在此,做个笔录,没想到多年没碰Android,现在还是初恋的感觉 哈哈^_^。在这希望能帮到各个技术攻城狮。基本多部分都是参考以下文章编写而成,在此非常感谢!这位大佬无私贡献。

源码(csdn代码仓库):Ch_champion / MyCompass · CODE CHINA

参考文章:

android学习笔记之磁场传感器制做指南针_晓晓的博客-CSDN博客

Android指南针应用编写相关推荐

  1. Android.mk文件编写

    Android.mk文件编写的例子: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello LOCAL_SR ...

  2. Android驱动(1)---Ubuntu中为Android系统上编写Linux内核驱动程序实现方法

    Ubuntu中为Android系统上编写Linux内核驱动程序实现方法 本文主要介绍在Ubuntu 上为Android系统编写Linux内核驱动程序, 这里对编写驱动程序做了详细的说明,对研究Andr ...

  3. android指南针功能,轻松实现Android指南针功能

    本文实例为大家讲解如何轻松实现Android指南针功能,分享给大家供大家参考.具体如下: (1)布局文件如下: android:layout_width="fill_parent" ...

  4. 《教我兄弟学Android逆向01 编写第一个Android程序》

    前言 之所以准备写这一系列逆向的教程是因为有一些同学私信我说自己想学习Android逆向但是不知道怎么去学习 包括自己身边的一些计算机专业的同学 在大学里面老师讲的那些东西要么是自己不感兴趣 要么是自 ...

  5. android studio调用python,Android studio中编写Python代码-2

    Chaquopy 教程 Chaquopy Chaquopy的作用:使用Chaquopy在Android Studio添加Python环境,java和Python互调 目前调试后APP可以正常运行(20 ...

  6. 安卓(Android studio)编写一个计算器,可以连续加减乘除,可加小数点,不包含括号以及加减乘除优先算法。

    安卓(Android studio)编写一个计算器,可以累加,可加小数点,不包含括号以及加减乘除优先算法. 首先需要在res目录下的layout文件下创建一个xml文件进行界面的布局设计,接着在Jav ...

  7. 怎么新建android.mk,Android NDK简单编写HelloWorld过程笔记(详细)

    Android NDK,坑啊,对于不会c的人来说更是坑啊,弄了一整天才把程序调出来,在网上找了各种资料,各种解决出现的bug,终于是能够运行了. 考虑了一下,还是做个目录吧. 1.创建一个项目 2.编 ...

  8. cocos2dx3.8 android打包脚本编写

    cocos集成了打包命令 cocos compile -p android 在这里并没有采用这个方案,而是编写自己的脚本, 理由如下 脚本掌握在自己手中可以第一时间解决和发现bug 游戏项目总会出现各 ...

  9. 03_Android NDK中C语言调用Java代码,javah的使用,javap的使用以及生成签名,Android.mk的编写,C代码的编写

     1  案例场景,通过C语言回调Java的代码,案例的最终界面: 2  案例的代码结构如下: 3 编写DataProvider的代码: package com.example.ndkcallbac ...

  10. Android NDK--自己编写调用JNI

    其实ubuntu中android开发环境的搭建也很简单 (1)下载android-sdk (2)为Eclipse安装ADT,从help->Install New SoftWare进入,地址输入h ...

最新文章

  1. PCL点云配准(2)
  2. 人人都能搞懂的AI(四)- AI对社会的影响
  3. 海思3559移植yolov3
  4. C#编程总结(七)数据加密——附源码
  5. python简单的监控脚本-利用socket、psutil阻止远程主机运行特定程序
  6. oracle 创建表中又有表,oracle创建表
  7. ProgressBar控件在Listview下的多线程应用(转自johngeng)
  8. day35-hibernate映射 03-Hibernate持久态对象自动更新数据库
  9. 1562a检测软件_洛达1562a空间音频版评测!!!
  10. How to: Configure an Azure SQL Database firewall using the Azure Portal
  11. Java实现UDP功能
  12. 重磅!颜宁宣布离美归国
  13. hdoj3709(数位dp)
  14. 国产化复旦微电子 FMQL45T900 FPGA开发板( 替代Xilinx ZYNQ ARM+FPGA 7045开发板)
  15. 360 os3.0 android7.1,360手机N5s发布:升级基于安卓7.1的360 OS 2.0系统
  16. 海贼王英文版 ONE PIECE百度网盘
  17. 根据关键词取商品列表API 返回值说明
  18. 个人笔记 springboot整合shiro实现权限管理,前端使用vue 10155
  19. DOM自定义属性 getAttribute、setAttribute、removeAttribute
  20. Java体系总结 cf2e3d1401904217a28c0bd2d09c5e72

热门文章

  1. 2022年ICASSP说话人日志(Speaker Diarization)方向论文泛读总结
  2. 使用HttpClient发送短信
  3. 一个人能懒到什么地步?
  4. python中3个单引号,Pyhton3中单引号、双引号、三个引号的用法和区别
  5. Hyperledger Fabric(1) - 整体架构和源码结构
  6. mysql got signal 11_mysqld got signal 11问题定位
  7. Unable to launch WebDriverAgent because of xcodebuild failure: “iproxy exited with code ‘234‘“
  8. 【Unity性能优化】ASTC压缩格式(Android)
  9. 计算机休眠和睡眠省电,几步教会你笔记本睡眠和休眠有什么区别
  10. 典型企业设备链路冗余备份方案