少部分Android应用可以将用户输入或者特定的数字转化为二维码,以方便应用的一些场景
此文章用到的开源库:ZXing
(Zebra Crossing
)
权限获得
确保应用有写入存储的权限,通过在AndroidManifest.xml
中添加相应的权限来实现将二维码保存到设备
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
添加依赖
在Android项目的build.gradle
文件中添加ZXing库的依赖项
dependencies {
implementation 'com.journeyapps:zxing-android-embedded:4.2.0'}
同步Gradle项目
生成二维码
使用ZXing提供的API创建生成二维码Bitmap的方法
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.journeyapps.barcodescanner.BarcodeEncoder;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import java.util.Hashtable;
public Bitmap createQRCode(String content) throws WriterException {
Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
BarcodeFormat.QR_CODE, 600, 600, hints);
BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
return barcodeEncoder.createBitmap(bitMatrix);
}
调用方法
在Activity
或者Fragment
中调用方法,并将生成的Bitmap显示在ImageView
上
try {
Bitmap bitmap = createQRCode("1234567890");
ImageView imageView = findViewById(R.id.qr_code_image_view);
imageView.setImageBitmap(bitmap);
} catch (WriterException e) {
e.printStackTrace();
}
其中1234567890
是用户输入或者特定的数字
保存图片
请求权限
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
} else {
saveImageToGallery();
}
获得权限后
private void saveImageToGallery() {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.your_image);
OutputStream fOut = null;
File file = null;
String filename = "your_image_name.png";
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), filename);
}
if (file == null) {
Log.d("SaveImage", "External storage not available");
return;
}
try {
fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
thisActivity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
} catch (IOException e) {
Log.e("SaveImage", e.getMessage());
}
}
处理权限请求结果
当用户响应权限请求时,会收到一个回调。需要处理这个回调来查看用户是否授予了所需的权限
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
saveImageToGallery();
} else {
Toast.makeText(thisActivity, "Permission denied", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
从Android 10(API级别29)开始,分区存储(Scoped Storage)对新应用默认启用,因此如果目标SDK版本设置为29或更高,则需要考虑使用MediaStore API来存储文件,或者请求主机权限(如
MANAGE_EXTERNAL_STORAGE
)