本文已参加「新人创作礼」活动,一起开启掘金创作之路
- 数据存储
- sharePreferences: Android提供用来以最原生的方式对数据进行永久保存的方法,保存文件格式为xml,储存在data/data/包名/shared_prefs
- 获取sharePreferences对象
- getSharedPreferences(String name,int mode)
- name 文件名
- mode MODE_PRIVATE 被本应用读写
- MODE_MULTI_PROCESS 跨应用读写
- getPerences(int mode)
- getSharedPreferences(String name,int mode)
- 获取SharedPreferences.Editor对象 edit()
- 向SharedPreferences.Editor对象添加数据 putBoolean(),putString(),putInt()
- 提交数据commit()
- 使用对象SharedPreferences类提供的getxx()方法获取数据
package com.jamin.datastorage; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private static final String account = "user"; private static final String pwd = "123456"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final EditText editAccount = findViewById(R.id.account); final EditText editPwd = findViewById(R.id.pwd); final SharedPreferences sharedPreferences = getSharedPreferences("userInfo", MODE_PRIVATE); final SharedPreferences.Editor editor = sharedPreferences.edit(); String user = sharedPreferences.getString("user", null); String password = sharedPreferences.getString("pwd", null); // 判断本地是否有数据 if (user != null && pwd != null && user.equals(account) && password.equals(pwd)) { Intent intent = new Intent(MainActivity.this, Main2Activity.class); startActivity(intent); } findViewById(R.id.login) .setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { String editAccountText = editAccount.getText().toString(); String editPwdText = editPwd.getText().toString(); // 验证 if (editAccountText.equals(account) && editPwdText.equals(pwd)) { Toast.makeText(MainActivity.this, "login success", Toast.LENGTH_SHORT).show(); // 储存数据 editor.putString("user", editAccountText); editor.putString("pwd", editPwdText); editor.commit(); Intent intent = new Intent(MainActivity.this, Main2Activity.class); startActivity(intent); } else { Toast.makeText(MainActivity.this, "login failed", Toast.LENGTH_SHORT).show(); Log.i("账号", editAccountText); Log.i("密码", editPwdText); editAccount.setText(""); editPwd.setText(""); } } }); } } - 获取sharePreferences对象
- 内部存储 应用的data/data/包名/files/内部储存文件
package com.jamin.datastorage; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * @author Jamin * @date 2019/10/11 * @desc 使用内部储存 * */ public class Main3Activity extends AppCompatActivity { private FileOutputStream fos = null; private FileInputStream fis = null; private byte[] buffer = null; private EditText editText2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); final EditText editText = findViewById(R.id.editText); editText2 = findViewById(R.id.editText2); // 保存文件 findViewById(R.id.saveButton) .setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { String content = editText.getText().toString(); try { fos = openFileOutput("test", MODE_PRIVATE); fos.write(content.getBytes()); fos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); Toast.makeText(Main3Activity.this, "保存成功", Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } } } } }); Button cancelButton = findViewById(R.id.cancelButton); cancelButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); // 打开保存的文件 Button openButton = findViewById(R.id.openButton); openButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { try { fis = openFileInput("test"); buffer = new byte[fis.available()]; fis.read(buffer); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); String data = new String(buffer); editText2.setText(data); } catch (IOException e) { e.printStackTrace(); } } } } }); } } - 使用外部存储
package com.jamin.datastorage; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * @author Jamin * @date 2019/1012 * @desc 外部存储 */ public class Main5Activity extends AppCompatActivity { private EditText editText3; private EditText editText4; private Button saveButton; private Button cancelButton; private Button openButton; private FileInputStream fis; private FileOutputStream fos; private byte[] buffer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main5); editText3 = findViewById(R.id.editText3); editText4 = findViewById(R.id.editText4); saveButton = findViewById(R.id.saveButton2); cancelButton = findViewById(R.id.cancelButton2); openButton = findViewById(R.id.openButton2); saveButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { String content = editText3.getText().toString(); File file = new File(Environment.getExternalStorageDirectory(), "/test.txt"); try { fos = new FileOutputStream(file); fos.write(content.getBytes()); fos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); Toast.makeText(Main5Activity.this, "保存成功", Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } } } } }); openButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { try { fis = new FileInputStream(Environment.getExternalStorageDirectory() + "/test.txt"); buffer = new byte[fis.available()]; fis.read(buffer); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); String content = new String(buffer); editText4.setText(content); } catch (IOException e) { e.printStackTrace(); } } } } }); } } - 使用sqlite数据库
- 在内部储存下新建文件夹dataBase,创建数据库,建表
- 实例代码
package com.jamin.datastorage; import android.content.ContentValues; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; /** * @author Jamin * @date 2019/10/12 * @desc 使用sqlite数据库进行添加 */ public class Main7Activity extends AppCompatActivity {; private DBOpenHelper dbOpenHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main7); // 初始化对象 dbOpenHelper = new DBOpenHelper(Main7Activity.this, "db_dict", null, 1); final EditText eeditText = findViewById(R.id.eeditText); final EditText ceditText = findViewById(R.id.ceditText); findViewById(R.id.add) .setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { String en = eeditText.getText().toString(); String cn = ceditText.getText().toString(); // 保存数据 ContentValues contentValues = new ContentValues(); contentValues.put("word", en); contentValues.put("deatil", cn); dbOpenHelper.getReadableDatabase().insert("t_dictionary", null, contentValues); Toast.makeText(Main7Activity.this, "add success", Toast.LENGTH_SHORT).show(); } }); } @Override protected void onDestroy() { super.onDestroy(); if (dbOpenHelper != null) { dbOpenHelper.close(); } } }package com.jamin.datastorage; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author Jamin * @date 2019/10/12 * @desc 使用sqlite数据库进行查询 */ public class Main6Activity extends AppCompatActivity { private DBOpenHelper dbOpenHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main6); // 实例化dbOpenHelper对象 上下文对象,数据库名,游标工厂,版本号 dbOpenHelper = new DBOpenHelper(Main6Activity.this, "db_dict", null, 1); final ListView listView = findViewById(R.id.listView); final EditText trEditText = findViewById(R.id.treditText); Button translationButton = findViewById(R.id.translation); Button newWordsButton = findViewById(R.id.newWords); // 跳转添加生词 newWordsButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(Main6Activity.this, Main7Activity.class)); } }); // 查询操作 translationButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Log.d("test", "in"); String en = trEditText.getText().toString(); // 查询 Cursor cursor = dbOpenHelper .getReadableDatabase() .query("t_dictionary", null, "word=?", new String[] {en}, null, null, null); List<Map<String, String>> maps = new ArrayList<>(); // 遍历放入集合 while (cursor.moveToNext()) { HashMap<String, String> map = new HashMap<>(); map.put("word", cursor.getString(1)); map.put("deatil", cursor.getString(2)); // Toast.makeText(Main6Activity.this, map.toString(), // Toast.LENGTH_SHORT).show(); Log.d("test", map.toString()); maps.add(map); } if (maps == null || maps.size() == 0) { Toast.makeText(Main6Activity.this, "没有查询到数据", Toast.LENGTH_SHORT).show(); } SimpleAdapter simpleAdapter = new SimpleAdapter( Main6Activity.this, maps, R.layout.result_main, new String[] {"word", "deatil"}, new int[] {R.id.result_en, R.id.result_cn}); // 适配器输出 listView.setAdapter(simpleAdapter); } }); } @Override protected void onDestroy() { super.onDestroy(); if (dbOpenHelper != null) { dbOpenHelper.close(); } } }
- 使用contentProvider 在不同应用程序间实现数据共享
- URI与URL
- URL: me.csdn.net/weixin_4389… URL协议/网站域名/网站资源
- URI: content://com.jamin.test/person/oo1 Android规定/权限(类名)/路径
package com.jamin.datastorage; import android.content.ContentResolver; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; /** * @author Jamin * @date 2019/10/12 * @desc contentProvider */ public class Main8Activity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main8); StringBuilder stringBuilder = new StringBuilder(); ContentResolver contentResolver = getContentResolver(); // 查询 Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); int columnIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); // 遍历查询结果 for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { String cursorString = cursor.getString(columnIndex); stringBuilder.append(cursorString + "\n"); } TextView textView = findViewById(R.id.textView); textView.setText(stringBuilder.toString()); } }
- URI与URL
- sharePreferences: Android提供用来以最原生的方式对数据进行永久保存的方法,保存文件格式为xml,储存在data/data/包名/shared_prefs
- Handler消息处理
- 安卓中的多线程
- 进程
- 进程: 一个android应用就是一个进程
- 线程
- 线程: 比进程更小的独立运行的基本单位,一个进程可以包含多个进程
- 实例代码
- 进程
- Handler对象
package com.jaminhandlermessage; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final TextView textView = findViewById(R.id.textView); final Handler handler = new Handler() { @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); // 判断消息 if (msg.what == 0x1234) { // 执行操作 textView.setText("测试2"); } } }; Button button = findViewById(R.id.bt1); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Thread thread = new Thread( new Runnable() { @Override public void run() { // 发送消息 handler.sendEmptyMessage(0x1234); } }); thread.start(); } }); } }package com.jamin.handlermessage; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.ProgressBar; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.jaminhandlermessage.R; /** * @author Jamin * @date 2019/10/13 * @desc 使用Handler实现进度条 */ public class Main2Activity extends AppCompatActivity { final int MSG = 0x1234; final int MSG2 = 0x1243; private int progress = 0; private int progress2 = 60; private ProgressBar progressBar; private ProgressBar progressBar2; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == MSG) { if (progress < 100) { progressBar.setProgress(++progress); handler.sendEmptyMessageDelayed(MSG, 1000); } else { Toast.makeText(Main2Activity.this, "加载完成", Toast.LENGTH_SHORT).show(); } } else if (msg.what == MSG2) { if (progress2 > 0) { progressBar2.setProgress(--progress2); handler.sendEmptyMessageDelayed(MSG2, 1000); } else { Toast.makeText(Main2Activity.this, "游戏结束!!", Toast.LENGTH_SHORT).show(); } } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); progressBar = findViewById(R.id.progressBar); handler.sendEmptyMessage(MSG); progressBar2 = findViewById(R.id.progressBar2); handler.sendEmptyMessage(MSG2); } } - Message对象
- 属性
- arg1 arg2 整形
- obj Object类型
- replyTo 发送到何处
- what 自定义消息代码
- 创建
- Mesage.obtain()
- Handler.obtainMessage()
- 属性
- Looper对象
package com.jamin.handlermessage; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import androidx.annotation.NonNull; /** * @author Jamin <br> * @date 2019/10/13 18:02 <br> * @desc Loop <br> */ public class LooperThread extends Thread { private final int MSG = 0x1234; private Handler handler; @Override public void run() { super.run(); Looper.prepare(); handler = new Handler() { @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); Log.e("looper", "test" + String.valueOf(MSG)); } }; Message message = handler.obtainMessage(); message.what = MSG; handler.sendMessage(message); Looper.loop(); } }package com.jamin.handlermessage; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import com.jaminhandlermessage.R; public class Main4Activity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main4); LooperThread looperThread = new LooperThread(); looperThread.start(); } }
- 安卓中的多线程
- Service
- 概述: 能够在后台长时间运行,并且没有用户界面的应用程序组件
- 分类
- started service:Activity使用startService通知服务启动才启动 生命周期onCreate->onStartCommand()-->Service运行-->stopSelf()/stopService-->service停止-->onDestory()-->service被关闭
- boundService: bindService()与Activity同生共死 生命周期 onCrate()--> onBind()-->绑定到Service-->unbindService()-->解绑Service()-->onUnbind()-->onDestory()-->service关闭()
- StartedService
package com.jamin.service; import android.app.ActivityManager; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.util.Log; import java.util.ArrayList; /** * @author Jamin * @date 2019/10/13 * @desc 后台打印 */ public class MyService extends Service { private int i = 0; public MyService() {} @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { new Thread( new Runnable() { @Override public void run() { while (isRunning()) { Log.d("CESHI", String.valueOf(++i)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }) .start(); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); } public boolean isRunning() { ActivityManager systemService = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); // 获取正在运行的服务 ArrayList<ActivityManager.RunningServiceInfo> runningServiceInfos = (ArrayList<ActivityManager.RunningServiceInfo>) systemService.getRunningServices(100); for (ActivityManager.RunningServiceInfo runningServiceInfo : runningServiceInfos) { // 判断是否是当前服务 if (runningServiceInfo .service .getClassName() .toString() .equals("com.jamin.service.MyService")) { return true; } } return false; } }package com.jamin.service; import android.content.Intent; import android.os.Bundle; import android.view.View; import androidx.appcompat.app.AppCompatActivity; public class ServiceActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_service); final Intent intent = new Intent(ServiceActivity.this, MyService.class); findViewById(R.id.open) .setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { startService(intent); } }); findViewById(R.id.close) .setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { stopService(intent); } }); } }package com.jamin.service; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.os.IBinder; /** * @author Jamin * @date 2019/10/13 * @desc 后台音乐播放 */ public class MusicService extends Service { private MediaPlayer mediaPlayer; public MusicService() {} @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { mediaPlayer = MediaPlayer.create(this, R.raw.mp31); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); } else { mediaPlayer.start(); } return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { // 停止播放 mediaPlayer.pause(); mediaPlayer.seekTo(0); // 释放资源 mediaPlayer.release(); super.onDestroy(); } }package com.jamin.service; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; /** * @author Jamin * @date 2019/10/13 * @desc 后台播放音乐 */ public class BackgroundSoundActivity extends AppCompatActivity { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_background_sound); button = findViewById(R.id.openClose); final Intent intent = new Intent(BackgroundSoundActivity.this, MusicService.class); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { /* MediaPlayer mediaPlayer = MediaPlayer.create(BackgroundSoundActivity.this, R.raw.mp31); mediaPlayer.start();*/ startService(intent); } }); } } - BoundService
package com.jamin.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * @author Jamin * @date 2019/10/14 BinderService */ public class BinderService extends Service { public BinderService() {} // 销毁 @Override public void onDestroy() { super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return new MyBinder(); } /** 产生随机数的方法 */ public List<String> randomNumber() { List list = new ArrayList<String>(); String s = ""; for (int i = 0; i < 7; i++) { int j = new Random().nextInt(33) + 1; if (j >= 10) { s = String.valueOf(j); } else { s = "0" + String.valueOf(j); } list.add(s); } return list; } /** 创建MyBinder内部类 */ public class MyBinder extends Binder { // 创建获取Service的方法 public BinderService getBinderService() { return BinderService.this; } } }package com.jamin.service; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.view.View; import android.widget.Button; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import java.util.List; /** * @author Jamin * @date 2019/10/14 */ public class Main2Activity extends AppCompatActivity { private BinderService binderService; /** textView的id */ private int[] textViewArr = new int[] {R.id.t0, R.id.t1, R.id.t2, R.id.t3, R.id.t4, R.id.t5, R.id.t6}; private Button button; /** service连接对象 */ private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { binderService = ((BinderService.MyBinder) service).getBinderService(); } @Override public void onServiceDisconnected(ComponentName name) {} }; @Override protected void onStart() { super.onStart(); Intent intent = new Intent(Main2Activity.this, BinderService.class); // 绑定Service bindService(intent, serviceConnection, BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // 解绑service unbindService(serviceConnection); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); button = findViewById(R.id.bt0); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { List<String> list = binderService.randomNumber(); for (int i = 0; i < list.size(); i++) { TextView textView = findViewById(textViewArr[i]); textView.setText(list.get(i)); } } }); } } - IntantService 普通service不能自动开启线程,自动销毁,IntentService可以
package com.jamin.service; import android.app.IntentService; import android.content.Intent; import android.util.Log; import androidx.annotation.Nullable; /** * @author Jamin <br> * @date 2019/10/14 16:53 <br> * @desc IntentService <br> */ public class MyIntentService extends IntentService { /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. */ public MyIntentService(String name) { super(name); } public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(@Nullable Intent intent) { Log.d("intentService", "开始"); long endTime = System.currentTimeMillis() + 20 * 1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } } } @Override public void onDestroy() { super.onDestroy(); Log.d("service", "jieshu"); } }package com.jamin.service; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; /** * @author Jamin * @date 2019/10/14 * @desc 普通Service */ public class MyService2 extends Service { public MyService2() {} @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("service", "开始"); long endTime = System.currentTimeMillis() + 20 * 1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } } return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d("service", "jieshu"); } }
- 传感器
- 分类
- 光线传感器
- 磁场传感器
- 加速传感器
- 方向传感器
- 光线传感器实例代码
package com.jamin.sensor; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; /** * @author Jamin * @date 2019/10/14 * @desc 光线传感器 */ public class LightActivity extends AppCompatActivity implements SensorEventListener { private SensorManager sensorManager; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_light); // 获取传感器管理器 sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); textView = findViewById(R.id.textView); } @Override protected void onResume() { super.onResume(); // 注册监听器 sensorManager.registerListener( this, sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_GAME); } @Override protected void onPause() { super.onPause(); // 取消注册监听器 sensorManager.unregisterListener(this); } @Override public void onSensorChanged(SensorEvent event) { float[] values = event.values; int type = event.sensor.getType(); if (type == Sensor.TYPE_LIGHT) { textView.setText("光线传感器:" + values[0]); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {} } - 磁场传感器实例代码
package com.jamin.sensor; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.AttributeSet; import android.view.View; import androidx.annotation.Nullable; /** * @author Jamin <br> * @date 2019/10/14 21:28 <br> * @desc 指针 <br> */ public class PointView extends View implements SensorEventListener { private SensorManager sensorManager; private Bitmap bitmap; private float[] value; private float floatX; private float floatY; public PointView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); // 监听器 sensorManager.registerListener( this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL); // 加载资源 bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.compass); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (bitmap != null) { // 设置画布选择角度 canvas.translate(super.getWidth() / 2, super.getWidth() / 2); if (floatY == 0 && floatX > 0) { canvas.rotate(90); } else if (floatY == 0 && floatX < 0) { canvas.rotate(-90); } else { if (floatY > 0) { canvas.rotate((float) Math.tanh(floatX / floatY) * 90); } else { canvas.rotate((float) (180 + Math.tanh(floatX / floatY) * 90)); } } } canvas.drawBitmap(bitmap, -bitmap.getWidth() / 2, -bitmap.getHeight() / 2, new Paint()); } @Override public void onSensorChanged(SensorEvent event) { float[] values = event.values; int type = event.sensor.getType(); if (type == Sensor.TYPE_MAGNETIC_FIELD) { floatX = values[0]; floatY = values[1]; super.postInvalidate(); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {} } - 方向传感器
- 实例代码
package com.jamin.sensor; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.AttributeSet; import android.util.Log; import android.view.View; import androidx.annotation.Nullable; /** * @author Jamin <br> * @date 2019/10/15 19:55 <br> * @desc 水平仪 <br> */ public class LevelView extends View implements SensorEventListener { /** 最大倾斜角度 */ private final int MAX_ANGLE = 30; private SensorManager sensorManager; /** 加速度传感器的值 */ private float[] accelerometerValues; /** 磁场传感器的值 */ private float[] magnticValues; /** 小球X坐标 */ private float bubbleX; /** 小球Y坐标 */ private float bubbleY; /** 小球 */ private Bitmap bubble; /** * @param context * @param attrs */ public LevelView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); // 注册磁场监听器 sensorManager.registerListener( this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_GAME); // 注册加速度监听器 sensorManager.registerListener( this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(bubble, bubble.getWidth() / 2, bubble.getHeight() / 2, new Paint()); } @Override public void onSensorChanged(SensorEvent event) { // 获取手机触发event的传感器的类型 int sensorType = event.sensor.getType(); switch (sensorType) { case Sensor.TYPE_ACCELEROMETER: accelerometerValues = event.values.clone(); Log.d("磁场传感器", accelerometerValues.toString()); break; case Sensor.TYPE_MAGNETIC_FIELD: magnticValues = event.values.clone(); Log.d("加速度传感器", magnticValues.toString()); break; default: break; } float[] R = new float[9]; float[] values = new float[3]; SensorManager.getRotationMatrix(R, null, accelerometerValues, magnticValues); SensorManager.getOrientation(R, values); // 手机沿着x轴倾斜 顶部0到-180 底部0-180 float xAngle = (float) Math.toDegrees(values[1]); // 手机沿着y轴倾斜 左侧是0-到-90 右侧是0-90 float yAngle = (float) Math.toDegrees(values[2]); getPostion(xAngle, yAngle); super.postInvalidate(); } private void getPostion(float xAngle, float yAngle) { // 获取小球x,y位于中间位置的x,y坐标 int x = (super.getWidth() - bubble.getWidth()) / 2; int y = (super.getHeight() - bubble.getHeight()) / 2; if (Math.abs(yAngle) <= MAX_ANGLE) { // y轴倾斜角度越大 小球x坐标越大 int i = (int) ((super.getWidth() - bubble.getWidth()) / 2 * xAngle / MAX_ANGLE); x += i; } else if (yAngle > MAX_ANGLE) { // 正的倾斜角度超出放在最左边 x = 0; } else { // 负的倾斜角度超出放在最右边 x = super.getWidth() - bubble.getWidth(); } if (Math.abs(xAngle) <= y) { // x轴倾斜角度越大小球x坐标越大 int i = (int) ((super.getHeight() - bubble.getHeight()) / 2 * yAngle / MAX_ANGLE); y -= i; } else if (xAngle > MAX_ANGLE) { y = 0; } else { y = super.getHeight() - bubble.getHeight(); } bubbleX = x; bubbleY = y; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {} }
- 实例代码
- 分类
- 位置服务
- LocationProvider
package com.jamin.locationprovider; import android.location.Criteria; import android.location.LocationManager; import android.location.LocationProvider; import android.os.Bundle; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import java.util.Iterator; import java.util.List; public class Main2Activity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); // 获取位置服务 LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); // 获取所有位置服务的提供 List<String> allProviders = locationManager.getAllProviders(); StringBuilder stringBuilder = new StringBuilder(); for (Iterator<String> iterator = allProviders.iterator(); iterator.hasNext(); ) { stringBuilder.append(iterator.next() + "\n"); } TextView textView = findViewById(R.id.tv0); textView.setText(stringBuilder.toString()); LocationProvider provider = locationManager.getProvider(LocationManager.GPS_PROVIDER); TextView textView1 = findViewById(R.id.tv1); textView1.setText(provider.getName()); // 创建过滤条件对象 Criteria criteria = new Criteria(); // 不收费 criteria.setCostAllowed(false); // 精度最精确 criteria.setAccuracy(Criteria.ACCURACY_FINE); // 耗电量最低 criteria.setPowerRequirement(Criteria.POWER_LOW); // 获取最佳位置服务 String bestProvider = locationManager.getBestProvider(criteria, true); TextView textView2 = findViewById(R.id.tv2); textView2.setText(bestProvider); } } - 获取经纬度
package com.jamin.locationprovider; import android.Manifest; import android.content.pm.PackageManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; public class Main3Activity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); textView = findViewById(R.id.lcoation); // 检查权限 if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // Activity#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for Activity#requestPermissions for more details. return; } locationManager.requestLocationUpdates( // 使用GPS LocationManager.GPS_PROVIDER, // 间隔时间1s 1000, // 位置间隔1米 1, // 位置更新监听器 new LocationListener() { @Override public void onLocationChanged(Location location) {} @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} }); Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); locationUpdate(lastKnownLocation); } private void locationUpdate(Location location) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("经度" + location.getLongitude()); stringBuilder.append("纬度" + location.getLatitude()); textView.setText(stringBuilder.toString()); } } - 百度地图的应用
package com.jamin.baidumap; import android.location.Location; import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.AppCompatActivity; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.CoordType; import com.baidu.mapapi.SDKInitializer; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.BitmapDescriptor; import com.baidu.mapapi.map.BitmapDescriptorFactory; import com.baidu.mapapi.map.MapStatus; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.MarkerOptions; import com.baidu.mapapi.map.MyLocationData; import com.baidu.mapapi.map.OverlayOptions; import com.baidu.mapapi.model.LatLng; /** * @author Jamin * @date 2019/10/23 * @desc 初始化地图并配置生命周期 */ public class MainActivity extends AppCompatActivity implements BDLocationListener { private MapView mapView; private BaiduMap baiduMap; // 防止每次定位都重新设置中心点和marker private boolean isFirstLocation = true; // 初始化LocationClient定位类 private LocationClient mLocationClient = null; // 经纬度 private double lat; private double lon; private boolean isFirst = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化sdk SDKInitializer.initialize(getApplicationContext()); // 设置经纬度类型 SDKInitializer.setCoordType(CoordType.GCJ02); setContentView(R.layout.activity_main); mapView = findViewById(R.id.bmapView); // 获取百度地图对象 baiduMap = mapView.getMap(); // 声明LocationClient类 mLocationClient = new LocationClient(this); // 注册监听函数 mLocationClient.registerLocationListener(this); initLocation(); // 开始定位 mLocationClient.start(); } private void locationUpdate(Location location) { if (location != null) { LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); Log.d("经纬度", location.getLatitude() + "--------" + location.getLongitude()); if (isFirst) { MapStatus mapStatus = new MapStatus.Builder().target(latLng).zoom(18f).build(); // 设置地图位置 baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(mapStatus)); isFirst = false; // 构造定位数据 MyLocationData myLocationData = new MyLocationData.Builder() // 准确性 .accuracy(location.getAccuracy()) // 方向 .direction(100) // 纬度 .latitude(location.getLatitude()) // 经度 .longitude(location.getLongitude()) .build(); // 设置定位数据 baiduMap.setMyLocationData(myLocationData); // 设置图标 BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo); // 构建Marker图标 BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo); // 构建MarkerOption,用于在地图上添加Marker OverlayOptions option = new MarkerOptions().position(latLng).icon(bitmap); // 在地图上添加Marker,并显示 baiduMap.addOverlay(option); } } else { Log.d("经纬度", "无法获取"); } } @Override protected void onStart() { super.onStart(); baiduMap.setMyLocationEnabled(true); } @Override protected void onStop() { super.onStop(); baiduMap.setMyLocationEnabled(false); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); mapView = null; } @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override public void onReceiveLocation(BDLocation bdLocation) { if (isFirst) { isFirst = false; // 设置并显示中心点 MyLocationData locData = new MyLocationData.Builder() .accuracy(bdLocation.getRadius()) .direction(bdLocation.getRadius()) .latitude(bdLocation.getLatitude()) .longitude(bdLocation.getLongitude()) .build(); baiduMap.setMyLocationData(locData); LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude()); MapStatus.Builder builder = new MapStatus.Builder(); builder.target(ll).zoom(18.0f); baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); } } /** 配置定位参数 */ private void initLocation() { LocationClientOption option = new LocationClientOption(); // 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备 option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); // 可选,默认gcj02,设置返回的定位结果坐标系 option.setCoorType("bd09ll"); // 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的 int span = 5000; option.setScanSpan(span); // 可选,设置是否需要地址信息,默认不需要 option.setIsNeedAddress(true); // 可选,默认false,设置是否使用gps option.setOpenGps(true); // 可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果 option.setLocationNotify(true); // 可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近” option.setIsNeedLocationDescribe(true); // 可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到 option.setIsNeedLocationPoiList(true); // 可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死 option.setIgnoreKillProcess(false); // 可选,默认false,设置是否收集CRASH信息,默认收集 option.SetIgnoreCacheException(false); // 可选,默认false,设置是否需要过滤GPS仿真结果,默认需要 option.setEnableSimulateGps(false); mLocationClient.setLocOption(option); } /** * 设置中心点和添加marker * * @param map * @param bdLocation * @param isShowLoc */ public void setPosition2Center(BaiduMap map, BDLocation bdLocation, Boolean isShowLoc) { MyLocationData locData = new MyLocationData.Builder() .accuracy(bdLocation.getRadius()) .direction(bdLocation.getRadius()) .latitude(bdLocation.getLatitude()) .longitude(bdLocation.getLongitude()) .build(); map.setMyLocationData(locData); if (isShowLoc) { LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude()); MapStatus.Builder builder = new MapStatus.Builder(); builder.target(ll).zoom(18.0f); map.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); } } }// 将jar和so文件放在libs文件夹下 导入jar包 sourceSets { main { jniLibs.srcDirs = ['libs'] } }<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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=".MainActivity"> <!--百度地图的view--> <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" /> </LinearLayout>
- LocationProvider