I'm making one sms backup and restore android app.
Unfortunately, my app cannot restore text messages on Xiaomi phones, including Redmi 3s with android 6, Redmi Note 11 with android 12, But in other phones, it performs SMS backup and restore operations very well.
How can I solve this bug?
Java codes:
我正在制作一款短信备份和还原安卓应用程序。不幸的是,我的应用程序无法在小米手机上还原短信,包括搭载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);
}
}
}
Also, in my MainActivity file, I've taken Manifest.permission.READ_SMS permission.
Update: I deleted all the text messages from the phone and there is no similar id and the error Logcat is no longer shown but The bug still remains and SMS messages cannot be restored only on Xiaomi phones.
此外,在我的MainActivity文件中,我获得了Manifest.permission.READ_SMS权限。更新:我删除了手机上的所有短信,没有类似的ID,也不再显示错误日志,但错误仍然存在,只有小米手机才能恢复短信。
更多回答
You're trying to insert the same id multiple times. You can't do that. If an sms with that id already exists in the db, it will fail like this.
您正在尝试多次插入相同的ID。你不能这么做。如果具有该ID的SMS已经存在于数据库中,则它将失败,如下所示。
Thank you @GabeSechan I deleted all the text messages from the phone and there is no similar id and the error Logcat is no longer shown but The bug still remains and SMS messages cannot be restored only on Xiaomi phones.
谢谢你@GabeSechan我删除了手机上所有的短信,没有类似的id,也不再显示错误日志猫,但错误仍然存在,短信无法恢复,只有在小米手机上。
When your "app cannot restore text messages", what exactly happens? Crash, stacktrace, error messages, actual vs expected results...
当你的应用程序无法恢复短信时,具体会发生什么?崩溃、堆栈跟踪、错误消息、实际结果与预期结果...
Hi @Jorn it doesn't display any errors or Crash in logcat just show in the Verbose: 2023-09-05 00:38:47.088 9563-9563/com.backupeamoozesh3 D/Names are: _id 2023-09-05 00:38:47.088 9563-9563/com.backupeamoozesh3 D/Names are: thread_id 2023-09-05 00:38:47.088 9563-9563/com.backupeamoozesh3 D/Names are: address 2023-09-05 00:38:47.089 9563-9563/com.backupeamoozesh3 D/Names are: mx_id_v2 2023-09-05 00:38:47.120 9563-9563/com.backupeamoozesh3 I/Toast: Show toast from OpPackageName:com.backupeamoozesh3, PackageName:com.backupeamoozesh3
嗨@Jorn它不显示任何错误或崩溃在logcat只是显示在详细:2023-09-05 00:38:47.088 9563-9563/com.backupeamoozesh3 D/名称是:2019 -09-05 00:38:47.088 9563-9563/com.backupeamoozesh3 D/Name are:thread_id 2019 -09-05 00:38:47.088 9563-9563/com.backupeamoozesh3 D/姓名是:地址2023-09-05 00:38:47.089 9563-9563/com.backupeamoozesh3 D/名称是:mx_id_v2 2023-09-05 00:38:47.120 9563-9563/com.backupeamoozesh3 I/Toast:显示来自OpPackageName:com.backupeamoozesh3,PackageName:com.backupeamoozesh3的toast
我是一名优秀的程序员,十分优秀!