原视频链接
<uses-permission android:name="android.permission.INTERNET" />
<application
android:usesCleartextTraffic="true">
<uses-library
android:name="org.apache.http.legacy"
android:required="true" />
application>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Environment.getExternalStorageDirectory()//--/storage/emulated/0/----这是sd卡的根目录
getFilesDir().getAbsolutePath()//--/data/user/0/com.example.myapplication/files/--这是软件权限目录
public static void getPermissions(Activity activity){
//判断sdk版本
if (Build.VERSION.SDK_INT>=23) {
//获取管理器
int request= ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
if (request!= PackageManager.PERMISSION_GRANTED)//如果缺少权限,进行权限申请
{
//准备缺少权限的集合,并准备一个回调id
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},20);
return;//
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 20:
if (grantResults.length > 0 && (grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED)) {
//同意了
} else {
//拒绝权限,当前界面退出
finish();
}
break;
}
}
https://v1.hitokoto.cn/
// 解析json
implementation 'com.google.code.gson:gson:2.8.5'
运行界面
// 初始化请求队列
String url = "https://v1.hitokoto.cn/";
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.add(new JsonObjectRequest(Request.Method.GET, url, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
gson = new Gson();
JsonEntity jsonEntity = gson.fromJson(jsonObject.toString(), JsonEntity.class);
// Log.d("NETWork", jsonEntity.getHitokoto());
Message message = new Message();
message.what = 0x01;
message.obj = jsonEntity.getHitokoto();
handler.sendMessage(message);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
}
}));
// 处理Message 修改主线程UI
Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what){
case 0x001:
mNetworkTvTest.setText(msg.obj.toString());
}
}
};
public class HttpUtils {
private static RequestQueue queue;
public static void get(String path, final Context context, Response.Listener<JSONObject> res) {
if(queue==null){
queue = Volley.newRequestQueue(context);
}
queue.add(new JsonObjectRequest(path, res, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(context, "访问失败", Toast.LENGTH_SHORT).show();
}
}));
}
public static void post(String path, final Context context, Response.Listener<JSONObject> res) {
if(queue==null){
queue = Volley.newRequestQueue(context);
}
queue.add(new JsonObjectRequest(Request.Method.POST, path, res, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(context, "访问失败", Toast.LENGTH_SHORT).show();
}
}));
}
}
调用
String url = "https://v1.hitokoto.cn/";
HttpUtils.get(url, getApplicationContext(), new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
// 成功调用的方法
Log.d("success", jsonObject.toString());
}
});
@Override
protected void onStart() {
super.onStart();
Log.d(testLog, "渲染");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(testLog, "重新渲染");
}
@Override
protected void onResume() {
super.onResume();
Log.d(testLog, "渲染数据");
}
@Override
protected void onPause() {
super.onPause();
Log.d(testLog, "页面显示完成");
}
@Override
protected void onStop() {
super.onStop();
Log.d(testLog, "页面显隐藏");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(testLog, "销毁");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(testLog, "创建界面");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_net_work_test);
setView();
initView();
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser){
//当前页面可见
Log.d("TestLog","可见");
}else {
//滑动并不可见了
Log.d("TestLog","不可见");
}
}
简单提示
Toast.makeText(getApplicationContext(), "提示", Toast.LENGTH_SHORT).show();
new AlertDialog.Builder(ViewPageTest.this)
.setTitle("标题")
.setMessage("内容")
.setIcon(R.mipmap.ic_launcher)
.setCancelable(false)
.setNegativeButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.show();
View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_button_test, null);
// 获取dialog内部的button并监听其点击效果
Button button = view.findViewById(R.id.button_bt_test);
// 如果是在Activity的话,上下文必须用当前的上下文才可以
// 如果是在Fragment的话,则可以用getApplicationContext()
AlertDialog dialog = new AlertDialog.Builder(ViewPageTest.this)
.setView(view)
.show();
// 设置点击按钮后的取消操作
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.cancel();
}
});
https://www.jianshu.com/p/859943121b05
implementation 'com.github.rey5137:material:1.2.5'
View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_button_test, null);
// 如果是在Activity的话,上下文必须用当前的上下文才可以
// 如果是在Fragment的话,则可以用getApplicationContext()
final BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(ButtonTest.this);
bottomSheetDialog
.contentView(view)
.inDuration(800)
.outDuration(800)
.cancelable(true)
.show;
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:duration="100"
android:drawable="@drawable/listimage01">
item><item android:duration="100"
android:drawable="@drawable/listimage02">
item><item android:duration="100"
android:drawable="@drawable/listimage03">
item><item android:duration="100"
android:drawable="@drawable/listimage04">
item>
animation-list>
<ImageView
android:id="@+id/anm_iv_test"
android:background="@drawable/anm_test01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
public class AnimationTest extends AppCompatActivity {
private ImageView mAnmIvTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation_test);
initView();
setView();
}
private void setView() {
AnimationDrawable animationDrawable = (AnimationDrawable)mAnmIvTest.getBackground();
animationDrawable.start();
}
private void initView() {
mAnmIvTest = (ImageView) findViewById(R.id.anm_iv_test);
}
}
<translate
android:fromXDelta="0%"
android:fromYDelta="0%"
android:toXDelta="50%"
android:toYDelta="0%"
android:duration="1000"
xmlns:android="http://schemas.android.com/apk/res/android" >
translate>
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_translate);
mAnmIvTest.startAnimation(animation);
<scale
android:fromXScale="0%"
android:fromYScale="0%"
android:toXScale="80%"
android:toYScale="80%"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
xmlns:android="http://schemas.android.com/apk/res/android">
scale>
private void setView() {
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_scale);
mAnmIvTest.startAnimation(animation);
}
private void initView() {
mAnmIvTest = (ImageView) findViewById(R.id.anm_iv_test);
}
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
xmlns:android="http://schemas.android.com/apk/res/android">
rotate>
private void setView() {
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_rotate);
mAnmIvTest.startAnimation(animation);
}
private void initView() {
mAnmIvTest = (ImageView) findViewById(R.id.anm_iv_test);
}
注意:这里范围是:0.0-1.0
<alpha
android:fromAlpha="0.2"
android:toAlpha="1"
android:duration="1000"
xmlns:android="http://schemas.android.com/apk/res/android">
alpha>
private void setView() {
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_alpha);
mAnmIvTest.startAnimation(animation);
}
private void initView() {
mAnmIvTest = (ImageView) findViewById(R.id.anm_iv_test);
}
mAnmIvTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ValueAnimator animator = ValueAnimator.ofInt(0,330);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
//获取当前的height值
//动态更新view的高度
mAnmIvTest.getLayoutParams().height = (int) (Integer)animator.getAnimatedValue();
mAnmIvTest.requestLayout();
}
});
animator.setDuration(1000);
animator.start();
}
});
// 组件、动画效果(translateX....)、1f->2f 从初始放大两倍
ObjectAnimator animatorX = ObjectAnimator.ofFloat(mAnmIvTest, "scaleX", 1f, 2f);
ObjectAnimator animatorY = ObjectAnimator.ofFloat(mAnmIvTest, "scaleY", 1f, 2f);
animatorX.setDuration(1000);
animatorY.setDuration(1000);
animatorX.start();
animatorY.start();
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="10%"
android:toXDelta="0%"
android:duration="500"/>
<alpha
android:fromAlpha="0.6"
android:toAlpha="1"
android:duration="500"/>
set>
<layoutAnimation
android:animationOrder="normal"
android:delay="0.5"
android:animation="@anim/anim_list_item_set"
xmlns:android="http://schemas.android.com/apk/res/android">
layoutAnimation>
<ListView
android:layoutAnimation="@anim/anim_list_set"/>
// 普通跳转
Intent intent = new Intent();
intent.setClass(getApplicationContext(), ButtonTest.class);
startActivity(intent);
<alpha
android:fromAlpha="1"
android:toAlpha="0"
android:duration="1000"
xmlns:android="http://schemas.android.com/apk/res/android">
alpha>
anin_out.xml
<alpha
android:fromAlpha="1"
android:toAlpha="0"
android:duration="1000"
xmlns:android="http://schemas.android.com/apk/res/android">
alpha>
Intent intent = new Intent();
intent.setClass(getApplicationContext(), ButtonTest.class);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(AnimationTest.this).toBundle());
overridePendingTransition(R.anim.anim_in,R.anim.anim_out);
注意:
overridePendingTransition方法一定在startActivity后面
overridePendingTransition:参数1:当前页面消失动画,参数2:下个页面进入动画
设置接收动画(跳转到哪个界面则在那个界面中设置接受)
getWindow().setEnterTransition(new Explode());//需要接收动画
在跳转的界面接收即可
Intent intent = new Intent();
intent.setClass(getApplicationContext(), ButtonTest.class);
startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(
// create后面的参数为(哪个组件接受、"共享的参数名")
AnimationTest.this, Pair.<View, String>create(mAnmIvTest,"iv_bt")).toBundle());
MediaPlayer.create(AnimationTest.this, R.raw.test);
try {
mediaPlayer.setDataSource("../music/samsara.mp3") ;
} catch (IOException e) {
e.printStackTrace();
}
mMediaPlayer.setDataSource("http://..../xxx.mp3") ;
- 使用异步: prepareAsync\
- 并缓存完成才能播放:setOnPreparedListener
mMediaPlayer.prepareAsync();
setOnPreparedListener
setOnBufferingUpdateListener
setOnCompletionListener
mediaPlayer.getCurrentPosition();
mediaPlayer.getDuration()
mediaPlayer.seekTo()
mediaPlayer.pause();
mediaPlayer.start();
mediaPlayer.stop();
<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:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activitys.MediaTest">
<SeekBar
android:id="@+id/media_sb_test"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
LinearLayout>
public class MediaTest extends AppCompatActivity {
private SeekBar mediaSbTest;
private MediaPlayer mediaPlayer;
Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
mediaSbTest.setProgress(mediaPlayer.getCurrentPosition());
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media_test);
initView();
setView();
}
private void setView() {
// 设置本地资源
// mediaPlayer = MediaPlayer.create(MediaTest.this, R.raw.test_01);
// 设置网络资源(如果设置了网络资源,则必须要设置为异步加载)
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource("http://downsc.chinaz.net/files/download/sound1/201206/1638.mp3");
// 异步缓存
mediaPlayer.prepareAsync();
// 监听是否缓存完成
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
int duration = mediaPlayer.getDuration();
mediaSbTest.setMax(duration);
}
});
// 监听缓存进度
mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
}
});
new Thread() {
@Override
public void run() {
while ( mediaPlayer.getCurrentPosition() <= mediaPlayer.getDuration()) {
try {
// 监听播放缓存进度
Message message = new Message();
handler.sendMessage(message);
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
mediaSbTest.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
int progress = seekBar.getProgress();
mediaPlayer.seekTo(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}catch (IOException e) {
}
}
private void initView() {
mediaSbTest = (SeekBar) findViewById(R.id.media_sb_test);
}
}
setVideoURI(Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.test_mp4));
setVideoPath("android.resource://"+getPackageName()+"/"+R.raw.test_mp4);
videoView.setVideoPath("https:/...");
缓存完成才能播放:setOnPreparedListener
//设置进度条
MediaController mc = new MediaController(AnimationTest.this); //注意上下文
videoView.setMediaController(mc);
setOnPreparedListener
setOnCompletionListener
seekTo
<VideoView
android:id="@+id/media_vv_test"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
/**
* 播放视频
*/
mediaVvTest.setVideoPath("android.resource://"+getPackageName()+"/"+R.raw.test_02);
mediaVvTest.start();
// 增加控制器并且绑定
MediaController mediaController = new MediaController(MediaTest.this);
mediaVvTest.setMediaController(mediaController);
传感器
SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);//获取传感器管理器
//创建一个SensorManager来获取系统的传感器服务
SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
implements SensorEventListener{}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
//监听回调
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
List<Sensor> sensorList;
// 实例化传感器管理者
// 得到设置支持的所有传感器的List
sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor : sensorList) {
Log.d("FDFDS", "onResume: " + sensor.getName());
}
//注册传感器
sm.registerListener((SensorEventListener) this, sm.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_NORMAL);
if(sensorEvent.sensor.getType() == Sensor.TYPE_GRAVITY) {
float X = sensorEvent.values[0];
float Y = sensorEvent.values[1];
float Z = sensorEvent.values[2];
Log.d("FDFDS","x方向的重力加速度\n" + X);
Log.d("FDFDS","Y方向的重力加速度\n" + Y);
Log.d("FDFDS","Z方向的重力加速度\n" + Z);
}
//注册传感器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_NORMAL);
if(sensorEvent.sensor.getType() == Sensor.TYPE_LIGHT){
float X = sensorEvent.values[0];
Log.d("FDFDS","光强度为为"+ X );
}
Intent Intent = new Intent(android.content.Intent.ACTION_DIAL, Uri.parse("tel:" + "123123123"));//跳转到拨号界面,同时传递电话号码
startActivity(Intent);
//指定联系人
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:我是指定联系人"));
intent.putExtra("sms_body", "内容");
startActivity(intent);
<!--拍照-->
<uses-permission android:name="android.permission.CAMERA" />```
- 动态获取权限
- 隐式跳转
```java
//跳转相机
private void toCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //跳转到 ACTION_IMAGE_CAPTURE
//判断内存卡是否可用,可用的话就进行存储
//putExtra:取值,Uri.fromFile:传一个拍照所得到的文件,fileImg.jpg:文件名
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(),"fileImg.jpg")));
startActivityForResult(intent,101); // 101: 相机的返回码参数(随便一个值就行,只要不冲突就好)
}
//跳转相机动态权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}
推荐阅读
FingerprintManager manager;
KeyguardManager mKeyManager;
private final static int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 0;
private final static String TAG = "finger_log";
manager = (FingerprintManager) this.getSystemService(Context.FINGERPRINT_SERVICE);
mKeyManager = (KeyguardManager) this.getSystemService(Context.KEYGUARD_SERVICE);
@RequiresApi(api = Build.VERSION_CODES.M)
public boolean isFinger() {
//android studio 上,没有这个会报错
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "没有指纹识别权限", Toast.LENGTH_SHORT).show();
return false;
}
Log(TAG, "有指纹权限");
//判断硬件是否支持指纹识别
if (!manager.isHardwareDetected()) {
Toast.makeText(this, "没有指纹识别模块", Toast.LENGTH_SHORT).show();
return false;
}
Log(TAG, "有指纹模块");
//判断 是否开启锁屏密码
if (!mKeyManager.isKeyguardSecure()) {
Toast.makeText(this, "没有开启锁屏密码", Toast.LENGTH_SHORT).show();
return false;
}
Log(TAG, "已开启锁屏密码");
//判断是否有指纹录入
if (!manager.hasEnrolledFingerprints()) {
Toast.makeText(this, "没有录入指纹", Toast.LENGTH_SHORT).show();
return false;
}
Log(TAG, "已录入指纹");
return true;
}
CancellationSignal mCancellationSignal = new CancellationSignal();
//回调方法
FingerprintManager.AuthenticationCallback mSelfCancelled = new FingerprintManager.AuthenticationCallback() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
//但多次指纹密码验证错误后,进入此方法;并且,不能短时间内调用指纹验证
Toast.makeText(MediaTest.this, errString, Toast.LENGTH_SHORT).show();
showAuthenticationScreen();
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
Toast.makeText(MediaTest.this, helpString, Toast.LENGTH_SHORT).show();
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
Toast.makeText(MediaTest.this, "指纹识别成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onAuthenticationFailed() {
Toast.makeText(MediaTest.this, "指纹识别失败", Toast.LENGTH_SHORT).show();
}
};
@RequiresApi(api = Build.VERSION_CODES.M)
public void startListening(FingerprintManager.CryptoObject cryptoObject) {
//android studio 上,没有这个会报错
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "没有指纹识别权限", Toast.LENGTH_SHORT).show();
return;
}
manager.authenticate(cryptoObject, mCancellationSignal, 0, mSelfCancelled, null);
}
/**
* 锁屏密码
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void showAuthenticationScreen() {
Intent intent = mKeyManager.createConfirmDeviceCredentialIntent("finger", "测试指纹识别");
if (intent != null) {
startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) {
// Challenge completed, proceed with using cipher
if (resultCode == RESULT_OK) {
Toast.makeText(this, "识别成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "识别失败", Toast.LENGTH_SHORT).show();
}
}
}
private void Log(String tag, String msg) {
Log.d(tag, msg);
}
if (isFinger()) {
Toast.makeText(MediaTest.this, "请进行指纹识别", Toast.LENGTH_LONG).show();
startListening(null);
}
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-permission android:name="android.permission.NFC" />
public class NfcUtils {
//nfc
public NfcAdapter mNfcAdapter;
public static IntentFilter[] mIntentFilter = null;
public static PendingIntent mPendingIntent = null;
public static String[][] mTechList = null;
public NfcUtils(Activity activity) {
mNfcAdapter = NfcCheck(activity);
NfcInit(activity);
}
/**
* 检查NFC是否打开
*/
public static NfcAdapter NfcCheck(Activity activity) {
NfcAdapter mNfcAdapter = NfcAdapter.getDefaultAdapter(activity);
if (mNfcAdapter == null) {
Toast.makeText(activity, "设备不支持NFC功能!", Toast.LENGTH_SHORT).show();
return null;
} else {
if (!mNfcAdapter.isEnabled()) {
IsToSet(activity);
} else {
Toast.makeText(activity, "NFC功能已打开!", Toast.LENGTH_SHORT).show();
}
}
return mNfcAdapter;
}
/**
* 初始化nfc设置
*/
public static void NfcInit(Activity activity) {
Intent intent = new Intent(activity, activity.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
mPendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);
//做一个IntentFilter过滤你想要的action 这里过滤的是ndef
IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
//如果你对action的定义有更高的要求,比如data的要求,你可以使用如下的代码来定义intentFilter
// IntentFilter filter2 = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
// try {
// filter.addDataType("*/*");
// } catch (IntentFilter.MalformedMimeTypeException e) {
// e.printStackTrace();
// }
// mIntentFilter = new IntentFilter[]{filter, filter2};
// mTechList = null;
try {
filter.addDataType("*/*");
} catch (IntentFilter.MalformedMimeTypeException e) {
e.printStackTrace();
}
mTechList = new String[][]{{MifareClassic.class.getName()},
{NfcA.class.getName()}};
//生成intentFilter
mIntentFilter = new IntentFilter[]{filter};
}
/**
* 读取NFC的数据
*/
public static String readNFCFromTag(Intent intent) throws UnsupportedEncodingException {
Parcelable[] rawArray = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawArray != null) {
NdefMessage mNdefMsg = (NdefMessage) rawArray[0];
NdefRecord mNdefRecord = mNdefMsg.getRecords()[0];
if (mNdefRecord != null) {
String readResult = new String(mNdefRecord.getPayload(), "UTF-8");
return readResult;
}
}
return "";
}
/**
* 往nfc写入数据
*/
public static void writeNFCToTag(String data, Intent intent) throws IOException, FormatException {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Ndef ndef = Ndef.get(tag);
ndef.connect();
NdefRecord ndefRecord = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ndefRecord = NdefRecord.createTextRecord(null, data);
}
NdefRecord[] records = {ndefRecord};
NdefMessage ndefMessage = new NdefMessage(records);
ndef.writeNdefMessage(ndefMessage);
}
/**
* 读取nfcID
*/
public static String readNFCId(Intent intent) throws UnsupportedEncodingException {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String id = ByteArrayToHexString(tag.getId());
return id;
}
/**
* 将字节数组转换为字符串
*/
private static String ByteArrayToHexString(byte[] inarray) {
int i, j, in;
String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
String out = "";
for (j = 0; j < inarray.length; ++j) {
in = (int) inarray[j] & 0xff;
i = (in >> 4) & 0x0f;
out += hex[i];
i = in & 0x0f;
out += hex[i];
}
return out;
}
private static void IsToSet(final Activity activity) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage("是否跳转到设置页面打开NFC功能");
// builder.setTitle("提示");
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
goToSet(activity);
dialog.dismiss();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
private static void goToSet(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BASE) {
// 进入设置系统应用权限界面
Intent intent = new Intent(Settings.ACTION_SETTINGS);
activity.startActivity(intent);
return;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {// 运行系统在5.x环境使用
// 进入设置系统应用权限界面
Intent intent = new Intent(Settings.ACTION_SETTINGS);
activity.startActivity(intent);
return;
}
}
}
NfcUtils nfcUtils = new NfcUtils(this);
//设定intentfilter和tech-list。如果两个都为null就代表优先接收任何形式的TAG action。也就是说系统会主动发TAG intent。
if (nfcUtils.mNfcAdapter != null) {
nfcUtils.mNfcAdapter.enableForegroundDispatch(this, NfcUtils.mPendingIntent, NfcUtils.mIntentFilter, NfcUtils.mTechList);
}else {
Toast.makeText(this, "调用失败", Toast.LENGTH_SHORT).show();
}
一般在生命周期的onResume(渲染数据)方法中判断
@Override
protected void onDestroy() {
super.onDestroy();
nfcUtils.mNfcAdapter = null;
}
@Override
protected void onPause() {
super.onPause();
if (nfcUtils.mNfcAdapter != null) {
nfcUtils.mNfcAdapter.disableForegroundDispatch(this);
}
}
//在onNewIntent中处理由NFC设备传递过来的intent
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e(TAG, "--------------NFC-------------" );
processIntent(intent);
}
// 这块的processIntent() 就是处理卡中数据的方法
public void processIntent(Intent intent) {
Parcelable[] rawmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);//获取数据
Toast.makeText(this, "读取成功!", Toast.LENGTH_SHORT).show();
}
public class MyService extends Service {
@Override
public void onDestroy() {
super.onDestroy();
Log.d(BasDataUtil.LOG_TOAST, "服务销毁;");
}
@Override
public void onCreate() {
super.onCreate();
Log.d(BasDataUtil.LOG_TOAST, "服务创建----Create");
}
public MyService() {
Log.d(BasDataUtil.LOG_TOAST, "实例化MyService服务");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(BasDataUtil.LOG_TOAST, "服务----绑定成功");
// TODO: Return the communication channel to the service.
//返回到服务的通信通道。
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
String activityKey = intent.getStringExtra("data");
if (activityKey!=null){
//intent传入的参数接收
}
}catch (Exception e){
Log.d(BasDataUtil.LOG_TOAST,"播放音乐服务--发广播/收广播错误:"+e.toString());
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(BasDataUtil.LOG_TOAST, "解绑MyService成功");
return super.onUnbind(intent);
}
}
注意:
启动服务调用的是onCreate
关闭服务调用的是:onDestroy
绑定服务调用的是onBind
取消绑定调用的是:onUnbind
intent传参数 跳转 服务,需要接收使用:onStartCommand,与服务进行绑定
Intent intent = new Intent(this, MyService.class);
startService(intent);
private LocalBroadcastManager localBroadcastManager; //准备发送广播控制器
@Override
public void onCreate() {
localBroadcastManager = LocalBroadcastManager.getInstance(this); //实例化
super.onCreate();
Log.d(BasDataUtil.LOG_TOAST, "服务----Create");
}
//--------发送广播
Intent intent = new Intent("com.example.Service"); //准备一个intent:并实例一个标识:可使用自己的包名
intent.putExtra("dataKey", "dataKey的值");//需要传入的参数
localBroadcastManager.sendBroadcast(intent); //使用广播发送器发送
private LocalReceiver localReceiver;
private IntentFilter intentFilter;
///--提供广播监听
//监听广播
class LocalReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
try {
String dataKey = intent.getStringExtra("dataKey");
//判定获取是否成功
}catch (Exception e){
Log.d(BasDataUtil.LOG_TOAST,"播放接收广播错误:"+e.toString());
}
}
}
//--在该页注册广播
@Override
protected void onStart() {
//注册本地广播监听器
intentFilter = new IntentFilter(); //实例
intentFilter.addAction("com.example.Service");//绑定标识
localReceiver = new LocalReceiver(); //实例
//广播
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(PlayListActivity.this);//通过getInstance()得到LocalBroadcastManager的实例;
localBroadcastManager.registerReceiver(localReceiver, intentFilter);//启动广播接收
super.onStart();
}
//准备一个给页面调用的类
class PlayMusicBinder extends Binder {//例如这里可以直接播放,暂停,继续...各种操作
public PlayMusicBinder() {
//初始化控制器
mediaPlayer = new MediaPlayer();
}
public String getData(){
return "这是服务中的方法";
}
}
//准备一个IBinder,与页面交互:绑定立马调用
@Override
public IBinder onBind(Intent intent) {
Log.d(BasDataUtil.LOG_TOAST, "服务----绑定成功");
// TODO: Return the communication channel to the service.
return new PlayMusicBinder(); //返回服务中的Binder类
}
PlayMusicBinder playMusicBinder;
//--准备一个接收服务管理器:绑定后直接调用
private ServiceConnection connection = new ServiceConnection() {
/**
* 连接到服务
* @param name
* @param service
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//连接服务成功
playMusicBinder = (PlayMusicBinder) service;//这里就直接获取了playMusicBinder控制
}
/**
* 断开连接
* @param name
*/
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
//--绑定服务
@Override
protected void onStart() {
// 绑定服务
bindService(new Intent(getApplicationContext(), AudioService.class), connection, Service.BIND_AUTO_CREATE);
super.onStart();
}
//---这个时候就可以直接使用了
playMusicBinder.getData();
全部代码
服务端代码
MyService.java
public class MyService extends Service {
MediaPlayer mediaPlayer;
String musicSrc = "暂无";
@Override
public void onDestroy() {
super.onDestroy();
Log.d(BaseData.LOG_TOAST, "服务销毁;");
}
@Override
public void onCreate() {
super.onCreate();
Log.d(BaseData.LOG_TOAST, "服务创建----Create");
}
public MyService() {
Log.d(BaseData.LOG_TOAST, "实例化MyService服务");
}
/**
* 绑定
* @param intent
* @return
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(BaseData.LOG_TOAST, "服务----绑定成功");
// TODO: Return the communication channel to the service.
//返回到服务的通信通道。
return new PlayMusicBinder();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
String activityKey = intent.getStringExtra("data");
if (activityKey!=null){
//intent传入的参数接收
}
}catch (Exception e){
Log.d(BaseData.LOG_TOAST,"播放音乐服务--发广播/收广播错误:"+e.toString());
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(BaseData.LOG_TOAST, "解绑MyService成功");
return super.onUnbind(intent);
}
class PlayMusicBinder extends Binder{
public PlayMusicBinder() {
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.test_01);
}
public void initMusic(String src){
musicSrc = src;
}
public void playMusic(){
if(mediaPlayer != null){
mediaPlayer.start();
}
}
public void stopMusic(){
if(mediaPlayer != null){
mediaPlayer.stop();
}
}
public void test(){
Log.d(BaseData.LOG_TOAST,"调用了服务的方法");
// 可以直接写入播放音乐的相关代码
}
}
界面交互代码
public class ServiceTest extends AppCompatActivity implements View.OnClickListener {
MyService.PlayMusicBinder playMusicBinder;
private Button mServiceBtInit;
private Button mServiceBtPlay;
private Button mServiceBtStop;
@Override
protected void onStart() {
super.onStart();
// 绑定服务
bindService(new Intent(getApplicationContext(), MyService.class), connection, Service.BIND_AUTO_CREATE);
}
/**
* 创建服务链接器
*/
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
// 链接成功
playMusicBinder = (MyService.PlayMusicBinder) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_test);
setView();
initView();
}
private void setView() {
// startActivity(new Intent(getApplicationContext(), ServiceTest2.class));
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.service_bt_init:
Toast.makeText(ServiceTest.this, "初始化", Toast.LENGTH_SHORT).show();
playMusicBinder.initMusic("sss");
break;
case R.id.service_bt_play:
Toast.makeText(ServiceTest.this, "开始", Toast.LENGTH_SHORT).show();
playMusicBinder.playMusic();
break;
case R.id.service_bt_stop:
Toast.makeText(ServiceTest.this, "停止", Toast.LENGTH_SHORT).show();
playMusicBinder.stopMusic();
break;
}
}
private void initView() {
mServiceBtInit = (Button) findViewById(R.id.service_bt_init);
mServiceBtPlay = (Button) findViewById(R.id.service_bt_play);
mServiceBtStop = (Button) findViewById(R.id.service_bt_stop);
mServiceBtInit.setOnClickListener(this);
mServiceBtPlay.setOnClickListener(this);
mServiceBtStop.setOnClickListener(this);
}
}
int i;
String s;
使用范围:当前代码块
public static int i;
public static String s;
使用范围:跨类可以使用
传入基础数据
跳转传入数据
Intent intent =new Intent(getApplicationContext(), Activity2.class);
intent.putExtra(“key01”,“value01”);
startActivity(intent);
接受传入的数据
Intent intent= getIntent();
Log.d(BaseData.LOG_TOAST,intent.getStringExtra(“key01”));
这里注意获取可能为null
传入对象
该类需要继承 implements Serializable ,才能被存入
注意:
这里使用Bundle来存入数据,使用方法和intent类似
它相当于一个集合
使用Bundle设置就得使用Bundle接受
使用范围:全软件,并与软件共存(因为它存在软件里的文件夹里(data/data/shared_perfs/文件名.xml))
SharedPreferences sharedPreferences = getSharedPreferences("testSp",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
它的数据会一直保存只能自己删除或卸载软件
editor.putString("key","testKey");
editor.apply();
// 指明为哪个本地文件
SharedPreferences sharedPreferences = getSharedPreferences("testSp",MODE_PRIVATE);
sharedPreferences.getString("keyName","默认值");
editor.remove("key");//根据键删除
editor.clear();//清空
public class SqlitHelper extends SQLiteOpenHelper {
private static String SQL_NAME = "testSql.db";
private static int SQL_VERSION = 1;
public SqlitHelper(@Nullable Context context) {
super(context, SQL_NAME, null, SQL_VERSION);
}
//注意这个方法只执行一次,所以在这创建表格
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table tb_user(name varchar(20),pwd varchar(20))";
db.execSQL(sql);
}
//注意这个是数据库更新才调用
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
注意:
这个可以当成模板,不需要死记
onCreate:注意这个方法只执行一次,所以在这创建表格
SqlitHelper sqlitHelper = new SqlitHelper(this);
SQLiteDatabase db = sqlitHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name","张三");
values.put("pwd","123");
db.insert("tb_user",null,values);
SqlitHelper sqlitHelper = new SqlitHelper(this);
SQLiteDatabase db = sqlitHelper.getWritableDatabase();
//创建游标对象
Cursor cursor = db.query("tb_user", new String[]{"name","pwd"}, null, null, null, null, null);
//利用游标遍历所有数据对象
while(cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String pwd = cursor.getString(cursor.getColumnIndex("pwd"));
Log.d(BaseData.LOG_TOAST,"数据库:"+name+","+pwd);
}
@DatabaseTable(tableName = "tb_user2")//创建表名
public class UserEntity implements Serializable {
@DatabaseField()
String name;
@DatabaseField()
String pwd;
@DatabaseField()
String age;
注意:
- DatabaseTable:注释写法,说明这个类对应表格名
- DatabaseField:这个属性就是一个键
- 其他写法
@ DatabaseField注解可以有以下字段:
columnName 列名,未指定时为字段名
dataType DataType类的类型的字段。通常的类型是从Java类的领域,并不需要指定。
defaultValue 默认值
width 宽度 默认是0,表示不限
canBeNull 是否允许为空,默认为true
id 主键 默认为false
generatedId 自增长的主键 默认值是false
generatedIdSequence 字符串名称的序列号 类同generatedId,但您可以指定序列的名称使用。默认为null
foreign 外键,默认为false,字段不能是一个原始类型。在外键对象的类中,必须要有一个ID字段(ID, generatedId,generatedIdSequence)
useGetSet 应用get和set方法访问。默认为false
unknownEnumName 表示该字段是一个Java的枚举类型
throwIfNull 如果为空值,抛出一个异常 默认为false
persisted 是否在数据库中存储这个领域 默认为true
format 指定某一特定领域的信息格式,如指定日期字符串的格式
unique 唯一约束,默认为false
uniqueCombo 唯一行,该行内所有字段成为一个唯一约束,如有firstName 和 lastName两个字段,为"张"和"梅",那么该表内不可再插 入"张","梅", 但你可插入"张","全梅"。
index 是否建立索引 默认为false
uniqueIndex 唯一索引 默认为false
indexName 为这一领域的索引添加一个名字
uniqueIndexName 为这一领域的索引添加一个唯一的名字
foreignAutoRefresh 当查询到一个外键对象时,是否自动刷新 如 Order表中有Account外键对象,当返回Order的记录时是否也返回Account的记录, 默认为false
maxForeignAutoRefreshLevel 为了防止无限递归或者无限循环时 需要用到该属性设置自动刷新的最高级别
allowGeneratedIdInsert 插入一个ID字段是否覆盖它生成的ID的对象 默认为false
columnDefinition 定义列,默认情况下,数据库类型是用于自动生成所需的SQL来创建列,所以该属性并不常用
foreignAutoCreate 在插入一个有外键对象的对象时,是否自动插入这个外键对象
version 行版本 当一个对象被更新,以防止数据损坏多个实体时更新在同一时间进行的保护
public class SqlitOrmHelper extends OrmLiteSqliteOpenHelper {
private static String SQL_NAME = "testSql.db";
private static int SQL_VERSION = 1;
public SqlitOrmHelper(Context context) {
super(context, SQL_NAME, null, SQL_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
//创建表格
try {
TableUtils.createTable(connectionSource, UserEntity.class);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int i, int i1) {
}
}
SqlitOrmHelper sqlitOrmHelper = new SqlitOrmHelper(this);
try {
Dao<UserEntity, ?> dao = sqlitOrmHelper.getDao(UserEntity.class);
}catch (SQLException e) {
e.printStackTrace();
}
Dao<UserEntity, ?> dao = sqlitOrmHelper.getDao(UserEntity.class);
UserEntity userEntity = new UserEntity();
userEntity.setName("张三orm");
userEntity.setPwd("张三orm");
userEntity.setAge("2");
dao.create(userEntity);
List<UserEntity> userEntities = dao.queryForAll();
Log.d(BaseData.LOG_TOAST,"查询成功:"+userEntities.toString());
DeleteBuilder<UserEntity, ?> userEntityDeleteBuilder = dao.deleteBuilder();
userEntityDeleteBuilder.where().eq("name","张三orm");
userEntityDeleteBuilder.delete();