我正在制作一条短信备份和恢复 Android 应用程序。
不幸的是,我的应用程序无法在小米手机上恢复短信,包括带有Android 6的Redmi 3s,带有Android 12的Redmi Note 11,但在其他手机中,它可以很好地执行短信备份和恢复操作。
我该如何解决这个错误?
Java代码:
public class SmsBackupActivity extends Activity {
private static final int DEF_SMS_REQ = 0;
Button btnBackup;
Button btnRestore;
AlertDialog dismiss;
SMSGettersSetters localSMSGettersSetters;
Cursor localCursor;
int i;
int j;
private static Context context;
ProgressDialog pDialog;
public List<SMSGettersSetters> smsBuffer = new ArrayList();
TextView tvLastBackup;
FileWriter write;
String[] xmlfile;
Uri localUri;
private void backupSMS() throws IOException {
this.smsBuffer.clear();
String str1 = getExternalFilesDir(null) + File.separator + "sms";
this.write = new FileWriter(str1 + File.separator + this.xmlfile[0] + ".xml");
localUri = Uri.parse("content://sms/");
ContentResolver localContentResolver = getContentResolver();
String[] arrayOfString1 = new String[8];
arrayOfString1[0] = "_id";
arrayOfString1[1] = "thread_id";
arrayOfString1[2] = "address";
arrayOfString1[3] = "person";
arrayOfString1[4] = "date";
arrayOfString1[5] = "body";
arrayOfString1[6] = "type";
arrayOfString1[7] = "read";
localCursor = localContentResolver.query(localUri, arrayOfString1, null, null, null);
String[] arrayOfString2 = new String[8];
arrayOfString2[0] = "_id";
arrayOfString2[1] = "thread_id";
arrayOfString2[2] = "address";
arrayOfString2[3] = "person";
arrayOfString2[4] = "date";
arrayOfString2[5] = "body";
arrayOfString2[6] = "type";
arrayOfString2[7] = "read";
localCursor.moveToFirst();
i = localCursor.getCount();
this.pDialog.setMax(i);
this.write.append("<?xml version='1.0' encoding='UTF-8'?>");
this.write.append('\n');
this.write.append("<smsall>");
this.write.append('\n');
while (true) {
localSMSGettersSetters = new SMSGettersSetters();
@SuppressLint("Range") String str2 = localCursor.getString(localCursor.getColumnIndex("_id"));
@SuppressLint("Range") String str3 = localCursor.getString(localCursor.getColumnIndex("thread_id"));
@SuppressLint("Range") String str4 = localCursor.getString(localCursor.getColumnIndex("address"));
@SuppressLint("Range") String str5 = localCursor.getString(localCursor.getColumnIndex("person"));
@SuppressLint("Range") String str6 = localCursor.getString(localCursor.getColumnIndex("date"));
@SuppressLint("Range") String str7 = localCursor.getString(localCursor.getColumnIndex("body")).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll(">", "'").replaceAll("'", "⁄");
@SuppressLint("Range") String str8 = localCursor.getString(localCursor.getColumnIndex("type"));
@SuppressLint("Range") String str9 = localCursor.getString(localCursor.getColumnIndex("read"));
localSMSGettersSetters.setId(str2);
localSMSGettersSetters.setThreadId(str3);
localSMSGettersSetters.setAddres(str4);
localSMSGettersSetters.setPerson(str5);
localSMSGettersSetters.setDate(str6);
localSMSGettersSetters.setBody(str7);
localSMSGettersSetters.setType(str8);
localSMSGettersSetters.setRead(str9);
localSMSGettersSetters.setSentDate(str1);
this.smsBuffer.add(localSMSGettersSetters);
Handler localHandler = new Handler(Looper.getMainLooper());
localHandler.post(new Runnable() {
@Override
public void run() {
final int m = j;
SmsBackupActivity.this.pDialog.setProgress(1 + m);
i++;
int v = -1 + i;
if (m == v) {
Log.d("dismiss", "is called");
SmsBackupActivity.this.pDialog.dismiss();
SmsBackupActivity.this.setBackupDate();
}
i--;
return;
}
});
generateXMLFileForSMS(localSMSGettersSetters);
localCursor.moveToNext();
j++;
if (j == i) {
this.write.append("</smsall>");
this.write.flush();
this.write.close();
pDialog.dismiss();
return;
}
}
}
private void generateXMLFileForSMS(SMSGettersSetters paramSMSGettersSetters) {
try {
this.write.append("<sms>");
this.write.append('\n');
this.write.append("<id>" + paramSMSGettersSetters.getId() + "</id>");
this.write.append('\n');
this.write.append("<threadId>" + paramSMSGettersSetters.getThreadId() + "</threadId>");
this.write.append('\n');
this.write.append("<address>" + paramSMSGettersSetters.getAddress() + "</address>");
this.write.append('\n');
this.write.append("<person>" + paramSMSGettersSetters.getPerson() + "</person>");
this.write.append('\n');
this.write.append("<date>" + paramSMSGettersSetters.getDate() + "</date>");
this.write.append('\n');
this.write.append("<body>" + paramSMSGettersSetters.getBody() + "</body>");
this.write.append('\n');
this.write.append("<type>" + paramSMSGettersSetters.getType() + "</type>");
this.write.append('\n');
this.write.append("<read>" + paramSMSGettersSetters.getRead() + "</read>");
this.write.append('\n');
this.write.append("</sms>");
this.write.append('\n');
return;
} catch (NullPointerException localNullPointerException) {
while (true)
System.out.println("Nullpointer Exception " + localNullPointerException);
} catch (IOException localIOException) {
while (true)
localIOException.printStackTrace();
} catch (Exception localException) {
while (true)
localException.printStackTrace();
}
}
private void launchComponent(String paramString1, String paramString2) {
Intent localIntent = new Intent("android.intent.action.MAIN");
localIntent.addCategory("android.intent.category.LAUNCHER");
localIntent.setComponent(new ComponentName(paramString1, paramString2));
startActivity(localIntent);
}
public void BackupAlert() {
AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);
View localView = getLayoutInflater().inflate(R.layout.layout_backup_dialog, null);
final EditText localEditText = (EditText) localView.findViewById(R.id.etFileName);
CharSequence localCharSequence = DateFormat.format("yyMMddhhmmss", new Date().getTime());
localEditText.setText("sms_" + localCharSequence + ".xml");
localBuilder.setView(localView);
localBuilder.setPositiveButton("ok", new OnClickListener() {
@Override
public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {
SmsBackupActivity.this.xmlfile = localEditText.getText().toString().trim().split(".xml");
SmsBackupActivity.this.setProgressDialog();
new Thread(new Runnable() {
@Override
public void run() {
try {
Looper.prepare();
SmsBackupActivity.this.backupSMS();
Looper.loop();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
});
localBuilder.setNegativeButton("cancel", null);
AlertDialog localAlertDialog = localBuilder.create();
localAlertDialog.getWindow().getAttributes().windowAnimations = R.style.PauseDialogAnimation;
localAlertDialog.show();
}
public String getBackupDate(String paramString) {
return getSharedPreferences("BackupPrefs", 0).getString(paramString, getString(R.string.never_backup));
}
public int getSMSCount() {
Cursor localCursor = getContentResolver().query(Uri.parse("content://sms/"), null, null, null, null);
String[] arrayOfString = localCursor.getColumnNames();
for (int i = 0; ; i++) {
if (i >= arrayOfString.length)
return localCursor.getCount();
Log.d("Names are", arrayOfString[i]);
}
}
public List<FileGetterSetters> getSMSFiles() {
ArrayList localArrayList = new ArrayList();
File[] arrayOfFile = new File(getExternalFilesDir(null) + File.separator + "sms").listFiles();
int i = arrayOfFile.length;
for (int j = 0; ; j++) {
if (j >= i)
return localArrayList;
File localFile = arrayOfFile[j];
FileGetterSetters localFileGetterSetters = new FileGetterSetters();
Log.d("file Name is", localFile.getName());
localFileGetterSetters.setFileName(localFile.getName());
Date localDate = new Date(localFile.lastModified());
Log.d("Modified date is", localDate.toString());
localFileGetterSetters.setDateCreated(localDate.toString());
localArrayList.add(localFileGetterSetters);
}
}
public String getXML(String paramString) {
Log.d("File path is", paramString);
File localFile = new File(paramString);
StringBuilder localStringBuilder = new StringBuilder();
try {
BufferedReader localBufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(localFile)));
while (true) {
String str = localBufferedReader.readLine();
if (str == null)
return localStringBuilder.toString();
localStringBuilder.append(str);
localStringBuilder.append('\n');
}
} catch (IOException localIOException) {
}
return paramString;
}
public void initAllViews() {
this.btnBackup = ((Button) findViewById(R.id.btnBackup));
this.btnRestore = ((Button) findViewById(R.id.btnRestore));
TextView localTextView1 = (TextView) findViewById(R.id.tvSMS);
this.tvLastBackup = ((TextView) findViewById(R.id.tvLastBackup));
btnBackup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (getSMSCount() > 0) {
SmsBackupActivity.this.BackupAlert();
} else {
Toast.makeText(getApplicationContext(), "SMS not found", Toast.LENGTH_SHORT).show();
}
}
});
btnRestore.setOnClickListener(new View.OnClickListener() {
@SuppressLint("NewApi")
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
RoleManager roleManager = (RoleManager) getSystemService(Context.ROLE_SERVICE);
if (roleManager != null && !roleManager.isRoleHeld(ROLE_SMS)) {
SmsReceiver.enable(SmsBackupActivity.this);
Intent intent = roleManager.createRequestRoleIntent(ROLE_SMS);
startActivityForResult(intent, DEF_SMS_REQ);
}
else {
SmsBackupActivity.this.restoreBackupFilesDialog(true);
}
} else {
if (!Telephony.Sms.getDefaultSmsPackage(getApplicationContext()).equals(getPackageName()))
{
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,getPackageName());
startActivityForResult(intent, DEF_SMS_REQ);
}
else
{
SmsBackupActivity.this.restoreBackupFilesDialog(true);
}
}
}
});
localTextView1.setText(Html.fromHtml("<font color='#FFFFFF'>SMS:</font>" + getSMSCount()));
this.tvLastBackup.setText(Html.fromHtml("<font color='#FFFFFF'>" + getString(R.string.last_backup) + ":</font>" + getBackupDate("smsBackupDate")));
}
public void okDialog() {
AlertDialog localAlertDialog = new AlertDialog.Builder(this).create();
localAlertDialog.setMessage(getString(R.string.deleted_successfully_));
localAlertDialog.setButton("ok", new OnClickListener() {
@Override
public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {
}
});
localAlertDialog.show();
}
@Override
protected void onCreate(Bundle paramBundle) {
super.onCreate(paramBundle);
setContentView(R.layout.layout_sms_backupt);
SmsBackupActivity.context = getApplicationContext();
initAllViews();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case DEF_SMS_REQ:
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT && isDefaultSmsApp(this) ||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.BASE && resultCode == Activity.RESULT_OK) {
SmsBackupActivity.this.restoreBackupFilesDialog(true);
}
break;
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public static boolean isDefaultSmsApp(Context context) {
return context.getPackageName().equals(getDefaultSmsPackage(context));
}
public void openInbox() {
try {
Intent localIntent = new Intent("android.intent.action.MAIN");
localIntent.addCategory("android.intent.category.LAUNCHER");
Iterator localIterator = getPackageManager().queryIntentActivities(localIntent, 0).iterator();
while (localIterator.hasNext()) {
ResolveInfo localResolveInfo = (ResolveInfo) localIterator.next();
if (localResolveInfo.activityInfo.packageName.equalsIgnoreCase("com.android.mms"))
launchComponent(localResolveInfo.activityInfo.packageName, localResolveInfo.activityInfo.name);
}
} catch (ActivityNotFoundException localActivityNotFoundException) {
}
}
@SuppressLint("NewApi")
public void restoreBackup(HashMap<String, String> paramHashMap) {
ContentValues localContentValues = new ContentValues();
localContentValues.put("address", paramHashMap.get("address"));
localContentValues.put("person", paramHashMap.get("person"));
localContentValues.put("date", paramHashMap.get("date"));
localContentValues.put("body", paramHashMap.get("body"));
localContentValues.put("_id", paramHashMap.get("id"));
localContentValues.put("type", paramHashMap.get("type"));
localContentValues.put("read", paramHashMap.get("read"));
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BASE) {
getContentResolver().insert(Telephony.Sms.CONTENT_URI, localContentValues);
} else {
getContentResolver().insert(Uri.parse("content://sms/"), localContentValues);
}
}catch (Exception e){
}
}
public void restoreBackupFilesDialog(final boolean paramBoolean) {
AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);
localBuilder.setTitle(R.string.backup_files);
ListView localListView = new ListView(this);
final List localList = getSMSFiles();
localListView.setAdapter(new FileAdapter(this, R.layout.item_row_file, localList));
localListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> paramAnonymousAdapterView, View paramAnonymousView, int paramAnonymousInt, long paramAnonymousLong) {
SmsBackupActivity.this.dismiss.dismiss();
if (paramBoolean) {
String str = getExternalFilesDir(null) + File.separator + "sms" + File.separator + ((FileGetterSetters) localList.get(paramAnonymousInt)).getFileName();
Log.d("Seleted file path is", str);
RestoringTask localRestoringTask = new RestoringTask(SmsBackupActivity.this);
String[] arrayOfString = new String[1];
arrayOfString[0] = str;
localRestoringTask.execute(arrayOfString);
}
}
});
localBuilder.setView(localListView);
localBuilder.setNegativeButton("cancel", null);
AlertDialog localAlertDialog = localBuilder.create();
localAlertDialog.getWindow().getAttributes().alpha = 0.6F;
localAlertDialog.getWindow().getAttributes().windowAnimations = R.style.FileDialogAnimation;
this.dismiss = localAlertDialog;
localAlertDialog.show();
}
public void setBackupDate() {
CharSequence localCharSequence = DateFormat.format("yy/MM/dd hh:mm:ss", new Date().getTime());
this.tvLastBackup.setText(Html.fromHtml("<font color='#FFFFFF'>" + getString(R.string.last_backup) + ":</font>" + localCharSequence.toString()));
setLastBackupDate("smsBackupDate", localCharSequence.toString());
}
public void setLastBackupDate(String paramString1, String paramString2) {
SharedPreferences.Editor localEditor = getSharedPreferences("BackupPrefs", 0).edit();
localEditor.putString(paramString1, paramString2);
localEditor.commit();
}
public void setProgressDialog() {
this.pDialog = new ProgressDialog(this);
this.pDialog.setMessage(getString(R.string.backuping_files_please_wait_));
this.pDialog.setIndeterminate(false);
this.pDialog.setProgressDrawable(getResources().getDrawable(R.drawable.greenprogress));
this.pDialog.setMax(100);
this.pDialog.setProgressStyle(1);
this.pDialog.setCancelable(true);
this.pDialog.show();
}
public void viewMessagesDialog() {
AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);
localBuilder.setMessage(getString(R.string.restore_completed_successfully_));
localBuilder.setPositiveButton(getString(R.string.view_messages), new OnClickListener() {
@Override
public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {
SmsBackupActivity.this.openInbox();
}
});
localBuilder.setNegativeButton("cancel", null);
AlertDialog localAlertDialog = localBuilder.create();
localAlertDialog.getWindow().getAttributes().windowAnimations = R.style.PauseDialogAnimation;
localAlertDialog.show();
}
public class RestoringTask extends AsyncTask<String, Integer, String> {
ProgressDialog pd = new ProgressDialog(SmsBackupActivity.this);
Integer[] arrayOfInteger;
public RestoringTask(SmsBackupActivity smsBackupActivity) {
}
@Override
@SuppressWarnings("unchecked")
protected String doInBackground(String[] paramArrayOfString) {
String str = SmsBackupActivity.this.getXML(paramArrayOfString[0]);
XMLParser localXMLParser = new XMLParser();
NodeList localNodeList = localXMLParser.getDomElement(str).getElementsByTagName("sms");
int i = localNodeList.getLength();
for (int j = 0; ; j++) {
if (j >= i)
return "";
@SuppressWarnings("rawtypes")
HashMap localHashMap = new HashMap();
Element localElement = (Element) localNodeList.item(j);
localHashMap.put("id", localXMLParser.getValue(localElement, "id"));
localHashMap.put("threadId", localXMLParser.getValue(localElement, "threadId"));
localHashMap.put("address", localXMLParser.getValue(localElement, "address"));
localHashMap.put("person", localXMLParser.getValue(localElement, "person"));
localHashMap.put("date", localXMLParser.getValue(localElement, "date"));
localHashMap.put("body", localXMLParser.getValue(localElement, "body"));
localHashMap.put("type", localXMLParser.getValue(localElement, "type"));
localHashMap.put("read", localXMLParser.getValue(localElement, "read"));
SmsBackupActivity.this.restoreBackup(localHashMap);
Integer[] arrayOfInteger = new Integer[2];
arrayOfInteger[0] = Integer.valueOf(i);
arrayOfInteger[1] = Integer.valueOf(j);
publishProgress(arrayOfInteger);
}
}
@Override
@SuppressLint("InlinedApi")
protected void onPostExecute(String paramString) {
super.onPostExecute(paramString);
((TextView) SmsBackupActivity.this.findViewById(R.id.tvSMS)).setText(Html.fromHtml("<font color='#FFFFFF'>SMS:</font>" + SmsBackupActivity.this.getSMSCount()));
this.pd.dismiss();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Toast.makeText(getApplicationContext(), "Restored successfully", Toast.LENGTH_SHORT).show();
} else {
SmsBackupActivity.this.viewMessagesDialog();
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
this.pd.setProgressStyle(1);
this.pd.setMessage(SmsBackupActivity.this.getString(R.string.restoring_backups_));
this.pd.setProgressDrawable(SmsBackupActivity.this.getResources().getDrawable(R.drawable.greenprogress));
this.pd.show();
}
@Override
protected void onProgressUpdate(Integer[] paramArrayOfInteger) {
this.pd.setMax(paramArrayOfInteger[0].intValue());
this.pd.setProgress(paramArrayOfInteger[1].intValue());
super.onProgressUpdate(paramArrayOfInteger);
}
}
}
此外,在我的 MainActivity 文件中,我已获取 Manifest.permission.READ_SMS 权限。
更新:我删除了手机上的所有短信,没有类似的id,不再显示错误Logcat,但错误仍然存在,短信无法恢复,仅在小米手机上。
我刚刚注意到重复 ID 的问题已得到解决。嗯,这个问题只存在于小米手机上。
尝试检查以下可能性。
如果问题仍然存在,请考虑在小米设备上进行短信备份和恢复的替代方法。小米的定制可能会与某些方法发生冲突。您可以探索使用小米官方备份和恢复 API(如果可用)等选项。